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.
Thanks, Paolo. //////////////
/cp 2018-11-08 Paolo Carlini <paolo.carl...@oracle.com> * parser.c (make_id_declarator): Add location_t parameter. (cp_parser_lambda_declarator_opt): Adjust call. (cp_parser_decomposition_declaration): Likewise. (cp_parser_alias_declaration): Likewise. (cp_parser_direct_declarator): Likewise. (cp_parser_member_declaration): Likewise. (cp_parser_objc_class_ivars): Likewise. * decl.c (grokdeclarator): Use declarator->id_loc in two error messages. /testsuite 2018-11-08 Paolo Carlini <paolo.carl...@oracle.com> * g++.dg/cpp0x/nsdmi-union6.C: Test locations too. * g++.dg/cpp0x/nsdmi6.C: Likewise. * g++.dg/ext/flexary4.C: Likewise. * g++.dg/ext/flexary9.C: Likewise. * g++.dg/other/incomplete2.C: Likewise. * g++.dg/parse/friend12.C: Likewise.
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" } };