diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 808e5b61b1e..c915d6415de 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -18346,6 +18346,11 @@ cp_parser_explicit_specialization (cp_parser* parser) --parser->num_template_parameter_lists; } +/* Preserve the attributes across a garbage collect (by making it a GC + root), which can occur when parsing a member function. */ + +static GTY(()) vec *cp_parser_decl_specs_attrs; + /* Parse a type-specifier. type-specifier: @@ -18438,8 +18443,12 @@ cp_parser_type_specifier (cp_parser* parser, /* Parse tentatively so that we can back up if we don't find a class-specifier. */ cp_parser_parse_tentatively (parser); + if (decl_specs->attributes) + vec_safe_push (cp_parser_decl_specs_attrs, decl_specs->attributes); /* Look for the class-specifier. */ type_spec = cp_parser_class_specifier (parser); + if (decl_specs->attributes) + cp_parser_decl_specs_attrs->pop (); invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, type_spec); /* If that worked, we're done. */ if (cp_parser_parse_definitely (parser)) diff --git a/gcc/testsuite/g++.dg/other/gc7.C b/gcc/testsuite/g++.dg/other/gc7.C new file mode 100644 index 00000000000..ab436bac72f --- /dev/null +++ b/gcc/testsuite/g++.dg/other/gc7.C @@ -0,0 +1,16 @@ +// PR c++/91416 - GC during late parsing collects live data. +// { dg-do compile } +// { dg-options "--param ggc-min-heapsize=0 --param ggc-min-expand=0" } + +__attribute__ ((unused)) struct S { + S() { } +} s; + +__attribute__ ((unused)) struct X { + void fn () + { + __attribute__ ((unused)) struct N { + N() { } + } n; + } +} x;