On Tue, Feb 19, 2019 at 02:44:55PM -0500, David Malcolm wrote: > How about something like this? (on top of Jakub's patch)
I had following queued for regtest, so if you want to go for the make_location ^~, you should change more spots. > pr89390.C: In function 'void foo()': > pr89390.C:9:6: error: '~A' is not a member of 'A' > 9 | A::~A (); // { dg-error "6: '~A' is not a member of 'A'" } > | ^~ > pr89390.C: In function 'void test_2()': > pr89390.C:17:10: error: '~ns::P' is not a member of 'ns::P' > 17 | ns::P::~P (); // { dg-error "10: '~ns::P' is not a member of > 'ns::P'" } > | ^~ > > (Presumably gcc 10 material at this point; not yet bootstrapped). I wouldn't say so, it actually is even a regression: $ /usr/src/gcc-6/obj/gcc/cc1plus -quiet pr89390.C pr89390.C: In function ‘void foo()’: pr89390.C:9:3: error: ‘~A’ is not a member of ‘A’ A::~A (); // { dg-error "'~A' is not a member of 'A'" } ^ $ /usr/src/gcc-7/obj/gcc/cc1plus -quiet pr89390.C In function ‘void foo()’: cc1plus: error: ‘~A’ is not a member of ‘A’ Feel free to take this over though. 2019-02-19 Jakub Jelinek <ja...@redhat.com> PR c++/89390 * parser.c (cp_parser_unqualified_id): For BIT_NOT_EXPR remember location of the ~ token and use it to build cp_expr. * g++.dg/diagnostic/pr89390.C (foo): Expect diagnostics at the right line. --- gcc/cp/parser.c.jj 2019-02-18 20:48:37.669649863 +0100 +++ gcc/cp/parser.c 2019-02-19 10:41:14.090972524 +0100 @@ -5976,6 +5976,7 @@ cp_parser_unqualified_id (cp_parser* par tree object_scope; tree scope; bool done; + location_t loc = token->location; /* Consume the `~' token. */ cp_lexer_consume_token (parser->lexer); @@ -6050,7 +6051,7 @@ cp_parser_unqualified_id (cp_parser* par && constructor_name_p (token->u.value, scope)))) { cp_lexer_consume_token (parser->lexer); - return build_nt (BIT_NOT_EXPR, scope); + return cp_expr (build_nt (BIT_NOT_EXPR, scope), loc); } /* ~auto means the destructor of whatever the object is. */ @@ -6061,7 +6062,7 @@ cp_parser_unqualified_id (cp_parser* par "%<~auto%> only available with " "-std=c++14 or -std=gnu++14"); cp_lexer_consume_token (parser->lexer); - return build_nt (BIT_NOT_EXPR, make_auto ()); + return cp_expr (build_nt (BIT_NOT_EXPR, make_auto ()), loc); } /* If there was an explicit qualification (S::~T), first look @@ -6152,7 +6153,7 @@ cp_parser_unqualified_id (cp_parser* par type_decl = cp_parser_identifier (parser); if (type_decl != error_mark_node) type_decl = build_nt (BIT_NOT_EXPR, type_decl); - return type_decl; + return cp_expr (type_decl, loc); } } /* If an error occurred, assume that the name of the @@ -6187,7 +6188,7 @@ cp_parser_unqualified_id (cp_parser* par "typedef-name %qD used as destructor declarator", type_decl); - return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)); + return cp_expr (build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)), loc); } case CPP_KEYWORD: --- gcc/testsuite/g++.dg/diagnostic/pr89390.C.jj 2019-02-19 09:38:21.816096390 +0100 +++ gcc/testsuite/g++.dg/diagnostic/pr89390.C 2019-02-19 10:41:58.867234266 +0100 @@ -6,5 +6,5 @@ enum class A { B, C }; void foo () { - A::~A (); // { dg-error "'~A' is not a member of 'A'" "" { target *-*-* } 0 } + A::~A (); // { dg-error "'~A' is not a member of 'A'" } } Jakub