Message ID | 1550605495-27345-1-git-send-email-dmalcolm@redhat.com |
---|---|
State | New |
Headers | show |
Series | Capture source location of dtors (PR c++/89390) | expand |
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 <jakub@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
On Tue, 2019-02-19 at 20:37 +0100, Jakub Jelinek wrote: > 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. Sorry about colliding here; I have no objections to your version of the patch (and yours seems more comprehensive). Dave
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ffecce4..e6fdb34 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5976,6 +5976,7 @@ cp_parser_unqualified_id (cp_parser* parser, tree object_scope; tree scope; bool done; + location_t tilde_loc = token->location; /* Consume the `~' token. */ cp_lexer_consume_token (parser->lexer); @@ -6049,8 +6050,14 @@ cp_parser_unqualified_id (cp_parser* parser, || (CLASS_TYPE_P (scope) && constructor_name_p (token->u.value, scope)))) { + /* Create a location with caret == start at the tilde, + finishing at the end of the peeked token, e.g: + ~class_name + ^~~~~~~~~~~. */ + location_t loc + = make_location (tilde_loc, tilde_loc, token->location); 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. */ diff --git a/gcc/testsuite/g++.dg/diagnostic/pr89390.C b/gcc/testsuite/g++.dg/diagnostic/pr89390.C index df35fcc..91a6422 100644 --- a/gcc/testsuite/g++.dg/diagnostic/pr89390.C +++ b/gcc/testsuite/g++.dg/diagnostic/pr89390.C @@ -6,5 +6,13 @@ enum class A { B, C }; void foo () { - A::~A (); // { dg-error "'~A' is not a member of 'A'" "" { target *-*-* } 0 } + A::~A (); // { dg-error "6: '~A' is not a member of 'A'" } +} + +namespace ns { enum class P { Q, R }; } + +void +test_2 () +{ + ns::P::~P (); // { dg-error "10: '~ns::P' is not a member of 'ns::P'" } }