Message ID | 9fae7281-9921-1a49-01f3-2bb8690b3577@oracle.com |
---|---|
State | New |
Headers | show |
Series | [C++] PR 84605 ("[7/8/9 Regression] internal compiler error: in xref_basetypes, at cp/decl.c:13818") | expand |
On 3/4/19 6:03 AM, Paolo Carlini wrote: > Hi, > > this error recovery regression too is rather easy to explain: since > Jason's fix for c++/79580 (r245587) when defining a type from within an > expression we pass ts_within_enclosing_non_class to xref_tag when we > call it from cp_parser_class_head. Thus, in the ill-formed testcases at > issue, cp_parser_class_head is called twice for the same 'type' returned > by xref_tag, and the second time TYPE_BINFO is already set while > TYPE_SIZE is still zero, thus the gcc_assert in xref_basetypes triggers. > A rather straightforward way to give again an error message instead of > crashing is rejecting TYPE_BEING_DEFINED too, additionally to > COMPLETE_TYPE_P. in the check placed between the xref_tag and the > xref_basetypes calls. The wording of the error message is probably a tad > suboptimal in the TYPE_BEING_DEFINED case, but I'm not sure it's worth > spending time and code on that, the issue appears anyway to be rather > rare and all the testcases I have are error-recovery ones. Tested > x86_64-linux. OK. Jason
Index: cp/parser.c =================================================================== --- cp/parser.c (revision 269342) +++ cp/parser.c (working copy) @@ -24021,8 +24021,11 @@ cp_parser_class_head (cp_parser* parser, cp_parser_check_class_key (class_key, type); /* If this type was already complete, and we see another definition, - that's an error. */ - if (type != error_mark_node && COMPLETE_TYPE_P (type)) + that's an error. Likewise if the type is already being defined: + this can happen, eg, when it's defined from within an expression + (c++/84605). */ + if (type != error_mark_node + && (COMPLETE_TYPE_P (type) || TYPE_BEING_DEFINED (type))) { error_at (type_start_token->location, "redefinition of %q#T", type); Index: testsuite/g++.dg/parse/crash69.C =================================================================== --- testsuite/g++.dg/parse/crash69.C (nonexistent) +++ testsuite/g++.dg/parse/crash69.C (working copy) @@ -0,0 +1,11 @@ +// PR c++/84605 + +struct b { + int x(((struct b {}))); // { dg-error "expected|redefinition" } +}; + +struct c { + struct d { + int x(((struct c {}))); // { dg-error "expected|redefinition" } + }; +};