Message ID | 7e0b3ae8-3c74-f2a3-29f3-351b1d105a4b@oracle.com |
---|---|
State | New |
Headers | show |
Series | [C++] PR 84636 ("internal compiler error: Segmentation fault (identifier_p()/grokdeclarator())") | expand |
On Mon, Nov 19, 2018 at 08:03:24PM +0100, Paolo Carlini wrote: > @@ -12245,8 +12246,9 @@ grokdeclarator (const cp_declarator *declarator, > error ("invalid use of %<::%>"); > return error_mark_node; > } > - else if (TREE_CODE (type) == FUNCTION_TYPE > - || TREE_CODE (type) == METHOD_TYPE) > + else if ((TREE_CODE (type) == FUNCTION_TYPE > + || TREE_CODE (type) == METHOD_TYPE) I know it's preexisting but we have FUNC_OR_METHOD_TYPE_P for this. Marek
Hi, On 19/11/18 23:24, Marek Polacek wrote: > On Mon, Nov 19, 2018 at 08:03:24PM +0100, Paolo Carlini wrote: >> @@ -12245,8 +12246,9 @@ grokdeclarator (const cp_declarator *declarator, >> error ("invalid use of %<::%>"); >> return error_mark_node; >> } >> - else if (TREE_CODE (type) == FUNCTION_TYPE >> - || TREE_CODE (type) == METHOD_TYPE) >> + else if ((TREE_CODE (type) == FUNCTION_TYPE >> + || TREE_CODE (type) == METHOD_TYPE) > I know it's preexisting but we have FUNC_OR_METHOD_TYPE_P for this. Ah, thanks! I guess I didn't notice that because the macro is defined in tree.h. I adjusted my first patch and I'll send a separate one for all the remaining instances (many!) in a separate patch. Thanks again, Paolo. //////////////////////// Index: cp/decl.c =================================================================== --- cp/decl.c (revision 266268) +++ cp/decl.c (working copy) @@ -12165,7 +12165,8 @@ grokdeclarator (const cp_declarator *declarator, } if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2 - && !(identifier_p (unqualified_id) + && !(unqualified_id + && identifier_p (unqualified_id) && IDENTIFIER_NEWDEL_OP_P (unqualified_id))) { cp_cv_quals real_quals = memfn_quals; @@ -12245,8 +12246,7 @@ grokdeclarator (const cp_declarator *declarator, error ("invalid use of %<::%>"); return error_mark_node; } - else if (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) + else if (FUNC_OR_METHOD_TYPE_P (type) && !bitfield) { int publicp = 0; tree function_context; Index: testsuite/g++.dg/parse/bitfield3.C =================================================================== --- testsuite/g++.dg/parse/bitfield3.C (revision 266263) +++ testsuite/g++.dg/parse/bitfield3.C (working copy) @@ -5,5 +5,5 @@ typedef void (func_type)(); struct A { - friend func_type f : 2; /* { dg-error "with non-integral type" } */ + friend func_type f : 2; /* { dg-error "20:.f. is neither function nor member function" } */ }; Index: testsuite/g++.dg/parse/bitfield6.C =================================================================== --- testsuite/g++.dg/parse/bitfield6.C (nonexistent) +++ testsuite/g++.dg/parse/bitfield6.C (working copy) @@ -0,0 +1,6 @@ +// PR c++/84636 + +typedef void a(); +struct A { +a: 1; // { dg-error "bit-field .\\<anonymous\\>. with non-integral type" } +};
... in fact I'm thinking that the below - which directly checks for unqualified_id to be non-null in both places - may be a better variant: among other things it means that for related testcases like: typedef void a(); struct A { a a1: 1; }; we get the location of a1 right (we could also change the diagnostics in grokbitfield to use DECL_SOURCE_LOCATION and exploit it), and the testsuite doesn't need adjustments. Tested x86_64-linux. Thanks, Paolo. //////////////// Index: cp/decl.c =================================================================== --- cp/decl.c (revision 266339) +++ cp/decl.c (working copy) @@ -12165,7 +12165,8 @@ grokdeclarator (const cp_declarator *declarator, } if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2 - && !(identifier_p (unqualified_id) + && !(unqualified_id + && identifier_p (unqualified_id) && IDENTIFIER_NEWDEL_OP_P (unqualified_id))) { cp_cv_quals real_quals = memfn_quals; @@ -12245,8 +12246,7 @@ grokdeclarator (const cp_declarator *declarator, error ("invalid use of %<::%>"); return error_mark_node; } - else if (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) + else if (FUNC_OR_METHOD_TYPE_P (type) && unqualified_id) { int publicp = 0; tree function_context; Index: testsuite/g++.dg/parse/bitfield6.C =================================================================== --- testsuite/g++.dg/parse/bitfield6.C (nonexistent) +++ testsuite/g++.dg/parse/bitfield6.C (working copy) @@ -0,0 +1,6 @@ +// PR c++/84636 + +typedef void a(); +struct A { +a: 1; // { dg-error "bit-field .\\<anonymous\\>. with non-integral type" } +};
On 11/21/18 7:03 PM, Paolo Carlini wrote: > ... in fact I'm thinking that the below - which directly checks for > unqualified_id to be non-null in both places - may be a better variant: > among other things it means that for related testcases like: > typedef void a(); > struct A > { a a1: 1; }; > we get the location of a1 right (we could also change the diagnostics in > grokbitfield to use DECL_SOURCE_LOCATION and exploit it), and the > testsuite doesn't need adjustments. Tested x86_64-linux. > - else if (TREE_CODE (type) == FUNCTION_TYPE > - || TREE_CODE (type) == METHOD_TYPE) > + else if (FUNC_OR_METHOD_TYPE_P (type) && unqualified_id) Maybe change this to else if (funcdecl_p) ? OK either way. Jason
Index: cp/decl.c =================================================================== --- cp/decl.c (revision 266268) +++ cp/decl.c (working copy) @@ -12165,7 +12165,8 @@ grokdeclarator (const cp_declarator *declarator, } if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2 - && !(identifier_p (unqualified_id) + && !(unqualified_id + && identifier_p (unqualified_id) && IDENTIFIER_NEWDEL_OP_P (unqualified_id))) { cp_cv_quals real_quals = memfn_quals; @@ -12245,8 +12246,9 @@ grokdeclarator (const cp_declarator *declarator, error ("invalid use of %<::%>"); return error_mark_node; } - else if (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) + else if ((TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == METHOD_TYPE) + && !bitfield) { int publicp = 0; tree function_context; Index: testsuite/g++.dg/parse/bitfield3.C =================================================================== --- testsuite/g++.dg/parse/bitfield3.C (revision 266263) +++ testsuite/g++.dg/parse/bitfield3.C (working copy) @@ -5,5 +5,5 @@ typedef void (func_type)(); struct A { - friend func_type f : 2; /* { dg-error "with non-integral type" } */ + friend func_type f : 2; /* { dg-error "20:.f. is neither function nor member function" } */ }; Index: testsuite/g++.dg/parse/bitfield6.C =================================================================== --- testsuite/g++.dg/parse/bitfield6.C (nonexistent) +++ testsuite/g++.dg/parse/bitfield6.C (working copy) @@ -0,0 +1,6 @@ +// PR c++/84636 + +typedef void a(); +struct A { +a: 1; // { dg-error "bit-field .\\<anonymous\\>. with non-integral type" } +};