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 <[email protected]>
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