Message ID | 4f8f3e21-9b13-76af-eed0-341687a86e2d@oracle.com |
---|---|
State | New |
Headers | show |
Series | [C++] Fix two grokdeclarator locations | expand |
Hi again, On 08/11/18 10:26, Paolo Carlini wrote: > Hi, > > two additional grokdeclarator locations that we can easily fix by > using declarator->id_loc. Slightly more interesting, testing revealed > a latent issue in the make_id_declarator uses: > cp_parser_member_declaration wasn't setting declarator->id_loc, thus I > decided to add a location_t parameter to make_id_declarator itself and > adjust all the callers. Tested x86_64-linux. PS: In my local tree I have the cp_parser_objc_class_ivars change using token->location instead of UNKNOWN_LOCATION, thus all the make_id_declarator calls should be completely fine location-wise. Paolo.
On 11/12/18 6:39 AM, Paolo Carlini wrote: > Hi again, > > On 08/11/18 10:26, Paolo Carlini wrote: >> Hi, >> >> two additional grokdeclarator locations that we can easily fix by >> using declarator->id_loc. Slightly more interesting, testing revealed >> a latent issue in the make_id_declarator uses: >> cp_parser_member_declaration wasn't setting declarator->id_loc, thus I >> decided to add a location_t parameter to make_id_declarator itself and >> adjust all the callers. Tested x86_64-linux. > > PS: In my local tree I have the cp_parser_objc_class_ivars change using > token->location instead of UNKNOWN_LOCATION, thus all the > make_id_declarator calls should be completely fine location-wise. Great, I was going to ask about that. Can I see that patch, then? Jason
Hi, On 14/11/18 01:30, Jason Merrill wrote: > On 11/12/18 6:39 AM, Paolo Carlini wrote: >> Hi again, >> >> On 08/11/18 10:26, Paolo Carlini wrote: >>> Hi, >>> >>> two additional grokdeclarator locations that we can easily fix by >>> using declarator->id_loc. Slightly more interesting, testing >>> revealed a latent issue in the make_id_declarator uses: >>> cp_parser_member_declaration wasn't setting declarator->id_loc, thus >>> I decided to add a location_t parameter to make_id_declarator itself >>> and adjust all the callers. Tested x86_64-linux. >> >> PS: In my local tree I have the cp_parser_objc_class_ivars change >> using token->location instead of UNKNOWN_LOCATION, thus all the >> make_id_declarator calls should be completely fine location-wise. > Great, I was going to ask about that. Can I see that patch, then? Thanks, well I didn't post it because it is a trivial incremental change vs the posted one. Attached. Paolo. ////////////////// Index: cp/decl.c =================================================================== --- cp/decl.c (revision 265869) +++ cp/decl.c (working copy) @@ -12408,8 +12408,9 @@ grokdeclarator (const cp_declarator *declarator, { if (unqualified_id) { - error ("field %qD has incomplete type %qT", - unqualified_id, type); + error_at (declarator->id_loc, + "field %qD has incomplete type %qT", + unqualified_id, type); cxx_incomplete_type_inform (strip_array_types (type)); } else @@ -12423,8 +12424,9 @@ grokdeclarator (const cp_declarator *declarator, { if (friendp) { - error ("%qE is neither function nor member function; " - "cannot be declared friend", unqualified_id); + error_at (declarator->id_loc, + "%qE is neither function nor member function; " + "cannot be declared friend", unqualified_id); return error_mark_node; } decl = NULL_TREE; Index: cp/parser.c =================================================================== --- cp/parser.c (revision 265869) +++ cp/parser.c (working copy) @@ -1452,7 +1452,7 @@ make_declarator (cp_declarator_kind kind) static cp_declarator * make_id_declarator (tree qualifying_scope, tree unqualified_name, - special_function_kind sfk) + special_function_kind sfk, location_t id_location) { cp_declarator *declarator; @@ -1477,7 +1477,8 @@ make_id_declarator (tree qualifying_scope, tree un declarator->u.id.qualifying_scope = qualifying_scope; declarator->u.id.unqualified_name = unqualified_name; declarator->u.id.sfk = sfk; - + declarator->id_loc = id_location; + return declarator; } @@ -10666,7 +10667,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser p = obstack_alloc (&declarator_obstack, 0); - declarator = make_id_declarator (NULL_TREE, call_op_identifier, sfk_none); + declarator = make_id_declarator (NULL_TREE, call_op_identifier, sfk_none, + LAMBDA_EXPR_LOCATION (lambda_expr)); quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr) ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST); @@ -10677,7 +10679,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser exception_spec, return_type, /*requires_clause*/NULL_TREE); - declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr); declarator->std_attributes = attributes; fco = grokmethod (&return_type_specs, @@ -13443,10 +13444,13 @@ cp_parser_decomposition_declaration (cp_parser *pa FOR_EACH_VEC_ELT (v, i, e) { if (i == 0) - declarator = make_id_declarator (NULL_TREE, e.get_value (), sfk_none); + declarator = make_id_declarator (NULL_TREE, e.get_value (), + sfk_none, e.get_location ()); else - declarator->u.id.unqualified_name = e.get_value (); - declarator->id_loc = e.get_location (); + { + declarator->u.id.unqualified_name = e.get_value (); + declarator->id_loc = e.get_location (); + } tree elt_pushed_scope; tree decl2 = start_decl (declarator, &decl_specs, SD_INITIALIZED, NULL_TREE, NULL_TREE, &elt_pushed_scope); @@ -19264,8 +19268,7 @@ cp_parser_alias_declaration (cp_parser* parser) /*declarator=*/NULL)) return error_mark_node; - declarator = make_id_declarator (NULL_TREE, id, sfk_none); - declarator->id_loc = id_location; + declarator = make_id_declarator (NULL_TREE, id, sfk_none, id_location); member_p = at_class_scope_p (); if (member_p) @@ -20669,9 +20672,8 @@ cp_parser_direct_declarator (cp_parser* parser, } declarator = make_id_declarator (qualifying_scope, unqualified_name, - sfk); + sfk, token->location); declarator->std_attributes = attrs; - declarator->id_loc = token->location; declarator->parameter_pack_p = pack_expansion_p; if (pack_expansion_p) @@ -23963,6 +23965,8 @@ cp_parser_member_declaration (cp_parser* parser) tree identifier; tree width; tree late_attributes = NULL_TREE; + location_t id_location + = cp_lexer_peek_token (parser->lexer)->location; if (named_bitfld) identifier = cp_parser_identifier (parser); @@ -24031,7 +24035,8 @@ cp_parser_member_declaration (cp_parser* parser) decl = grokbitfield (identifier ? make_id_declarator (NULL_TREE, identifier, - sfk_none) + sfk_none, + id_location) : NULL, &decl_specifiers, width, initializer, @@ -30585,7 +30590,7 @@ cp_parser_objc_class_ivars (cp_parser* parser) /* Get the name of the bitfield. */ declarator = make_id_declarator (NULL_TREE, cp_parser_identifier (parser), - sfk_none); + sfk_none, token->location); eat_colon: cp_lexer_consume_token (parser->lexer); /* Eat ':'. */ Index: testsuite/g++.dg/cpp0x/nsdmi-union6.C =================================================================== --- testsuite/g++.dg/cpp0x/nsdmi-union6.C (revision 265869) +++ testsuite/g++.dg/cpp0x/nsdmi-union6.C (working copy) @@ -5,7 +5,7 @@ struct F; // { dg-message "forward declar union U // { dg-message "not complete" } { - U u[1] = { 0 }; // { dg-error "incomplete type" } + U u[1] = { 0 }; // { dg-error "5:field .u. has incomplete type" } }; template<typename T> @@ -18,13 +18,13 @@ template union UT<int>; union UF { - F u[1] = { 0 }; // { dg-error "incomplete type" } + F u[1] = { 0 }; // { dg-error "5:field .u. has incomplete type" } }; template<typename T> union UFT { - F u[1] = { 0 }; // { dg-error "incomplete type" } + F u[1] = { 0 }; // { dg-error "5:field .u. has incomplete type" } }; template union UFT<int>; @@ -31,7 +31,7 @@ template union UFT<int>; struct S // { dg-message "not complete" } { - S s[1] = { 0 }; // { dg-error "incomplete type" } + S s[1] = { 0 }; // { dg-error "5:field .s. has incomplete type" } }; template<typename T> @@ -44,13 +44,13 @@ template class ST<int>; struct SF { - F s[1] = { 0 }; // { dg-error "incomplete type" } + F s[1] = { 0 }; // { dg-error "5:field .s. has incomplete type" } }; template<typename T> struct SFT { - F s[1] = { 0 }; // { dg-error "incomplete type" } + F s[1] = { 0 }; // { dg-error "5:field .s. has incomplete type" } }; template class SFT<int>; Index: testsuite/g++.dg/cpp0x/nsdmi6.C =================================================================== --- testsuite/g++.dg/cpp0x/nsdmi6.C (revision 265869) +++ testsuite/g++.dg/cpp0x/nsdmi6.C (working copy) @@ -4,5 +4,6 @@ struct A { typedef int int T; // { dg-error "two or more data types in declaration" } - struct T x[1] = { 0 }; // { dg-error "incomplete type|forward" } + struct T x[1] = { 0 }; // { dg-error "14:field .x. has incomplete type" } +// { dg-message "forward declaration" "" { target c++11 } .-1 } }; Index: testsuite/g++.dg/ext/flexary4.C =================================================================== --- testsuite/g++.dg/ext/flexary4.C (revision 265869) +++ testsuite/g++.dg/ext/flexary4.C (working copy) @@ -143,7 +143,7 @@ struct Sx23 { struct Sx24 { struct S; - S a_x []; // { dg-error "incomplete type" } + S a_x []; // { dg-error "5:field .a_x. has incomplete type" } }; struct Sx25 { Index: testsuite/g++.dg/ext/flexary9.C =================================================================== --- testsuite/g++.dg/ext/flexary9.C (revision 265869) +++ testsuite/g++.dg/ext/flexary9.C (working copy) @@ -136,7 +136,8 @@ struct Sx23 { // array warning. struct Sx24 { struct S; - S a_x [0]; // { dg-message "incomplete type|zero-size array" } + S a_x [0]; // { dg-error "5:field .a_x. has incomplete type" } +// { dg-warning "zero-size array" "" { target *-*-* } .-1 } }; struct Sx25 { Index: testsuite/g++.dg/other/incomplete2.C =================================================================== --- testsuite/g++.dg/other/incomplete2.C (revision 265869) +++ testsuite/g++.dg/other/incomplete2.C (working copy) @@ -5,7 +5,7 @@ struct A; struct B { - A a : 1; // { dg-error "incomplete" } + A a : 1; // { dg-error "5:field .a. has incomplete type .A" } }; struct S Index: testsuite/g++.dg/parse/friend12.C =================================================================== --- testsuite/g++.dg/parse/friend12.C (revision 265869) +++ testsuite/g++.dg/parse/friend12.C (working copy) @@ -2,5 +2,5 @@ struct A { - friend int i = 0; // { dg-error "cannot be declared friend" } + friend int i = 0; // { dg-error "14:.i. is neither function nor member function; cannot be declared friend" } };
OK. On Wed, Nov 14, 2018 at 4:26 AM Paolo Carlini <paolo.carlini@oracle.com> wrote: > > Hi, > > On 14/11/18 01:30, Jason Merrill wrote: > > On 11/12/18 6:39 AM, Paolo Carlini wrote: > >> Hi again, > >> > >> On 08/11/18 10:26, Paolo Carlini wrote: > >>> Hi, > >>> > >>> two additional grokdeclarator locations that we can easily fix by > >>> using declarator->id_loc. Slightly more interesting, testing > >>> revealed a latent issue in the make_id_declarator uses: > >>> cp_parser_member_declaration wasn't setting declarator->id_loc, thus > >>> I decided to add a location_t parameter to make_id_declarator itself > >>> and adjust all the callers. Tested x86_64-linux. > >> > >> PS: In my local tree I have the cp_parser_objc_class_ivars change > >> using token->location instead of UNKNOWN_LOCATION, thus all the > >> make_id_declarator calls should be completely fine location-wise. > > Great, I was going to ask about that. Can I see that patch, then? > > Thanks, well I didn't post it because it is a trivial incremental change > vs the posted one. Attached. > > Paolo. > > ////////////////// >
Index: cp/decl.c =================================================================== --- cp/decl.c (revision 265869) +++ cp/decl.c (working copy) @@ -12408,8 +12408,9 @@ grokdeclarator (const cp_declarator *declarator, { if (unqualified_id) { - error ("field %qD has incomplete type %qT", - unqualified_id, type); + error_at (declarator->id_loc, + "field %qD has incomplete type %qT", + unqualified_id, type); cxx_incomplete_type_inform (strip_array_types (type)); } else @@ -12423,8 +12424,9 @@ grokdeclarator (const cp_declarator *declarator, { if (friendp) { - error ("%qE is neither function nor member function; " - "cannot be declared friend", unqualified_id); + error_at (declarator->id_loc, + "%qE is neither function nor member function; " + "cannot be declared friend", unqualified_id); return error_mark_node; } decl = NULL_TREE; Index: cp/parser.c =================================================================== --- cp/parser.c (revision 265869) +++ cp/parser.c (working copy) @@ -1452,7 +1452,7 @@ make_declarator (cp_declarator_kind kind) static cp_declarator * make_id_declarator (tree qualifying_scope, tree unqualified_name, - special_function_kind sfk) + special_function_kind sfk, location_t id_location) { cp_declarator *declarator; @@ -1477,7 +1477,8 @@ make_id_declarator (tree qualifying_scope, tree un declarator->u.id.qualifying_scope = qualifying_scope; declarator->u.id.unqualified_name = unqualified_name; declarator->u.id.sfk = sfk; - + declarator->id_loc = id_location; + return declarator; } @@ -10666,7 +10667,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser p = obstack_alloc (&declarator_obstack, 0); - declarator = make_id_declarator (NULL_TREE, call_op_identifier, sfk_none); + declarator = make_id_declarator (NULL_TREE, call_op_identifier, sfk_none, + LAMBDA_EXPR_LOCATION (lambda_expr)); quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr) ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST); @@ -10677,7 +10679,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser exception_spec, return_type, /*requires_clause*/NULL_TREE); - declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr); declarator->std_attributes = attributes; fco = grokmethod (&return_type_specs, @@ -13443,10 +13444,13 @@ cp_parser_decomposition_declaration (cp_parser *pa FOR_EACH_VEC_ELT (v, i, e) { if (i == 0) - declarator = make_id_declarator (NULL_TREE, e.get_value (), sfk_none); + declarator = make_id_declarator (NULL_TREE, e.get_value (), + sfk_none, e.get_location ()); else - declarator->u.id.unqualified_name = e.get_value (); - declarator->id_loc = e.get_location (); + { + declarator->u.id.unqualified_name = e.get_value (); + declarator->id_loc = e.get_location (); + } tree elt_pushed_scope; tree decl2 = start_decl (declarator, &decl_specs, SD_INITIALIZED, NULL_TREE, NULL_TREE, &elt_pushed_scope); @@ -19264,8 +19268,7 @@ cp_parser_alias_declaration (cp_parser* parser) /*declarator=*/NULL)) return error_mark_node; - declarator = make_id_declarator (NULL_TREE, id, sfk_none); - declarator->id_loc = id_location; + declarator = make_id_declarator (NULL_TREE, id, sfk_none, id_location); member_p = at_class_scope_p (); if (member_p) @@ -20669,9 +20672,8 @@ cp_parser_direct_declarator (cp_parser* parser, } declarator = make_id_declarator (qualifying_scope, unqualified_name, - sfk); + sfk, token->location); declarator->std_attributes = attrs; - declarator->id_loc = token->location; declarator->parameter_pack_p = pack_expansion_p; if (pack_expansion_p) @@ -23963,6 +23965,8 @@ cp_parser_member_declaration (cp_parser* parser) tree identifier; tree width; tree late_attributes = NULL_TREE; + location_t id_location + = cp_lexer_peek_token (parser->lexer)->location; if (named_bitfld) identifier = cp_parser_identifier (parser); @@ -24031,7 +24035,8 @@ cp_parser_member_declaration (cp_parser* parser) decl = grokbitfield (identifier ? make_id_declarator (NULL_TREE, identifier, - sfk_none) + sfk_none, + id_location) : NULL, &decl_specifiers, width, initializer, @@ -30585,7 +30590,7 @@ cp_parser_objc_class_ivars (cp_parser* parser) /* Get the name of the bitfield. */ declarator = make_id_declarator (NULL_TREE, cp_parser_identifier (parser), - sfk_none); + sfk_none, UNKNOWN_LOCATION); eat_colon: cp_lexer_consume_token (parser->lexer); /* Eat ':'. */ Index: testsuite/g++.dg/cpp0x/nsdmi-union6.C =================================================================== --- testsuite/g++.dg/cpp0x/nsdmi-union6.C (revision 265869) +++ testsuite/g++.dg/cpp0x/nsdmi-union6.C (working copy) @@ -5,7 +5,7 @@ struct F; // { dg-message "forward declar union U // { dg-message "not complete" } { - U u[1] = { 0 }; // { dg-error "incomplete type" } + U u[1] = { 0 }; // { dg-error "5:field .u. has incomplete type" } }; template<typename T> @@ -18,13 +18,13 @@ template union UT<int>; union UF { - F u[1] = { 0 }; // { dg-error "incomplete type" } + F u[1] = { 0 }; // { dg-error "5:field .u. has incomplete type" } }; template<typename T> union UFT { - F u[1] = { 0 }; // { dg-error "incomplete type" } + F u[1] = { 0 }; // { dg-error "5:field .u. has incomplete type" } }; template union UFT<int>; @@ -31,7 +31,7 @@ template union UFT<int>; struct S // { dg-message "not complete" } { - S s[1] = { 0 }; // { dg-error "incomplete type" } + S s[1] = { 0 }; // { dg-error "5:field .s. has incomplete type" } }; template<typename T> @@ -44,13 +44,13 @@ template class ST<int>; struct SF { - F s[1] = { 0 }; // { dg-error "incomplete type" } + F s[1] = { 0 }; // { dg-error "5:field .s. has incomplete type" } }; template<typename T> struct SFT { - F s[1] = { 0 }; // { dg-error "incomplete type" } + F s[1] = { 0 }; // { dg-error "5:field .s. has incomplete type" } }; template class SFT<int>; Index: testsuite/g++.dg/cpp0x/nsdmi6.C =================================================================== --- testsuite/g++.dg/cpp0x/nsdmi6.C (revision 265869) +++ testsuite/g++.dg/cpp0x/nsdmi6.C (working copy) @@ -4,5 +4,6 @@ struct A { typedef int int T; // { dg-error "two or more data types in declaration" } - struct T x[1] = { 0 }; // { dg-error "incomplete type|forward" } + struct T x[1] = { 0 }; // { dg-error "14:field .x. has incomplete type" } +// { dg-message "forward declaration" "" { target c++11 } .-1 } }; Index: testsuite/g++.dg/ext/flexary4.C =================================================================== --- testsuite/g++.dg/ext/flexary4.C (revision 265869) +++ testsuite/g++.dg/ext/flexary4.C (working copy) @@ -143,7 +143,7 @@ struct Sx23 { struct Sx24 { struct S; - S a_x []; // { dg-error "incomplete type" } + S a_x []; // { dg-error "5:field .a_x. has incomplete type" } }; struct Sx25 { Index: testsuite/g++.dg/ext/flexary9.C =================================================================== --- testsuite/g++.dg/ext/flexary9.C (revision 265869) +++ testsuite/g++.dg/ext/flexary9.C (working copy) @@ -136,7 +136,8 @@ struct Sx23 { // array warning. struct Sx24 { struct S; - S a_x [0]; // { dg-message "incomplete type|zero-size array" } + S a_x [0]; // { dg-error "5:field .a_x. has incomplete type" } +// { dg-warning "zero-size array" "" { target *-*-* } .-1 } }; struct Sx25 { Index: testsuite/g++.dg/other/incomplete2.C =================================================================== --- testsuite/g++.dg/other/incomplete2.C (revision 265869) +++ testsuite/g++.dg/other/incomplete2.C (working copy) @@ -5,7 +5,7 @@ struct A; struct B { - A a : 1; // { dg-error "incomplete" } + A a : 1; // { dg-error "5:field .a. has incomplete type .A" } }; struct S Index: testsuite/g++.dg/parse/friend12.C =================================================================== --- testsuite/g++.dg/parse/friend12.C (revision 265869) +++ testsuite/g++.dg/parse/friend12.C (working copy) @@ -2,5 +2,5 @@ struct A { - friend int i = 0; // { dg-error "cannot be declared friend" } + friend int i = 0; // { dg-error "14:.i. is neither function nor member function; cannot be declared friend" } };