C++ PATCH for c++/91416 - GC during late parsing collects live data

Jason Merrill jason@redhat.com
Tue Aug 13 15:06:00 GMT 2019


On 8/12/19 4:37 AM, Richard Biener wrote:
> On Sun, Aug 11, 2019 at 7:12 PM Marek Polacek <polacek@redhat.com> wrote:
>>
>> This is a crash that points to a GC problem.  Consider this test:
>>
>>    __attribute__ ((unused)) struct S {
>>      S() { }
>>    } s;
>>
>> We're parsing a simple-declaration.  While parsing the decl specs, we parse the
>> attribute, which means creating a TREE_LIST using ggc_alloc_*.
>>
>> A function body is a complete-class context so when parsing the
>> member-specification of this class-specifier, we parse the bodies of the
>> functions we'd queued in cp_parser_late_parsing_for_member.  This then leads to
>> this call chain:
>> cp_parser_function_definition_after_declarator -> expand_or_defer_fn ->
>> expand_or_defer_fn_1 -> maybe_clone_body -> expand_or_defer_fn ->
>> cgraph_node::finalize_function -> ggc_collect.
>>
>> In this test, the ggc_collect call collects the TREE_LIST we had allocated, and
>> a crash duly ensues.  We can't avoid late parsing of members in this context,
>> so my fix is to bump function_depth, exactly following cp_parser_lambda_body.
>> Since we are performing late parsing, we know we have to be nested in a class.
>> (We still ggc_collect later, in c_parse_final_cleanups.)
> 
> So the struct S itself is properly referenced by a GC root?  If so why not
> attach the attribute list to the tentative struct instead?  Or do we
> fear we have
> other non-rooted data live at the point we collect?  If so shouldn't we instead
> bump function_depth when parsing a declaration in general?

It's already a significant issue for C++ that we only collect between 
function declarations, I'm concerned that this change will cause more 
memory problems.

Perhaps if we start parsing a class-specifier we could push the 
decl_specifiers onto a vec that is a GC root?

Jason

>> But here's the thing.  This goes back to ancient r104500, at least.  How has
>> this not broken before?  All you need to trigger it is to enable GC checking
>> and have a class with a ctor/member function, that has an attribute.

...and is defined in the declaration of something else?  Does it happen 
without declaring the variable 's'?

Jason



More information about the Gcc-patches mailing list