From: David Malcolm Date: Sat, 23 Feb 2019 01:19:38 +0000 (+0000) Subject: Capture source location of dtors (PR c++/89390) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c1753302087205dd9d5e9013c859623b261df060;p=gcc.git Capture source location of dtors (PR c++/89390) gcc/cp/ChangeLog: PR c++/89390 * parser.c (cp_parser_unqualified_id): Capture and use locations for destructors. gcc/testsuite/ChangeLog: PR c++/89390 * g++.dg/diagnostic/pr89390.C: Update expected location of error, renaming to a multicharacter name, so that start != finish. Add tests for dtor locations. From-SVN: r269145 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 83813919609..2a5056ad4af 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-02-22 David Malcolm + + PR c++/89390 + * parser.c (cp_parser_unqualified_id): Capture and use locations + for destructors. + 2019-02-22 Marek Polacek PR c++/89420 - ICE with CAST_EXPR in explicit-specifier. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 545047c91af..e976008e94d 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); @@ -6038,9 +6039,18 @@ cp_parser_unqualified_id (cp_parser* parser, } gcc_assert (!scope || TYPE_P (scope)); + token = cp_lexer_peek_token (parser->lexer); + + /* Create a location with caret == start at the tilde, + finishing at the end of the peeked token, e.g: + ~token + ^~~~~~. */ + location_t loc + = make_location (tilde_loc, tilde_loc, token->location); + /* If the name is of the form "X::~X" it's OK even if X is a typedef. */ - token = cp_lexer_peek_token (parser->lexer); + if (scope && token->type == CPP_NAME && (cp_lexer_peek_nth_token (parser->lexer, 2)->type @@ -6050,18 +6060,18 @@ cp_parser_unqualified_id (cp_parser* parser, && 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. */ if (cp_parser_is_keyword (token, RID_AUTO)) { if (cxx_dialect < cxx14) - pedwarn (input_location, 0, + pedwarn (loc, 0, "%<~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 +6162,7 @@ cp_parser_unqualified_id (cp_parser* parser, 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 @@ -6168,7 +6178,7 @@ cp_parser_unqualified_id (cp_parser* parser, if (declarator_p && scope && !check_dtor_name (scope, type_decl)) { if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) - error_at (token->location, + error_at (loc, "declaration of %<~%T%> as member of %qT", type_decl, scope); cp_parser_simulate_error (parser); @@ -6183,11 +6193,11 @@ cp_parser_unqualified_id (cp_parser* parser, && !DECL_IMPLICIT_TYPEDEF_P (type_decl) && !DECL_SELF_REFERENCE_P (type_decl) && !cp_parser_uncommitted_to_tentative_parse_p (parser)) - error_at (token->location, + error_at (loc, "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: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4d3d307d4a6..4751104d106 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-02-22 David Malcolm + + PR c++/89390 + * g++.dg/diagnostic/pr89390.C: Update expected location of error, + renaming to a multicharacter name, so that start != finish. Add + tests for dtor locations. + 2019-02-22 Paolo Carlini PR c++/84676 diff --git a/gcc/testsuite/g++.dg/diagnostic/pr89390.C b/gcc/testsuite/g++.dg/diagnostic/pr89390.C index 8dae827a219..2e8c95a4d16 100644 --- a/gcc/testsuite/g++.dg/diagnostic/pr89390.C +++ b/gcc/testsuite/g++.dg/diagnostic/pr89390.C @@ -1,10 +1,48 @@ // PR c++/89390 // { dg-do compile { target c++11 } } +// { dg-options "-fdiagnostics-show-caret" } -enum class A { B, C }; +enum class bar { A, B, C }; void foo () { - A::~A (); // { dg-error "'~A' is not a member of 'A'" "" { target *-*-* } 0 } + bar::~bar (); // { dg-error "8: '~bar' is not a member of 'bar'" } + /* { dg-begin-multiline-output "" } + bar::~bar (); + ^~~~ + { dg-end-multiline-output "" } */ } + +namespace ns { enum class baz { P, Q, R }; } + +void +test_2 () +{ + ns::baz::~baz (); // { dg-error "12: '~ns::baz' is not a member of 'ns::baz'" } + /* { dg-begin-multiline-output "" } + ns::baz::~baz (); + ^~~~ + { dg-end-multiline-output "" } */ +} + +struct first; +struct second; +second::~first() {} // { dg-error "9: declaration of '~first' as member of 'second'" } + /* { dg-begin-multiline-output "" } + second::~first() {} + ^~~~~~ + { dg-end-multiline-output "" } */ + +struct test { ~test(); }; +typedef test test_t; +~test_t(); // { dg-error "typedef-name 'test_t' used as destructor declarator" } +// { dg-error "expected" "" { target *-*-* } .-1 } + /* { dg-begin-multiline-output "" } + ~test_t(); + ^~~~~~~ + { dg-end-multiline-output "" } */ + /* { dg-begin-multiline-output "" } + ~test_t(); + ^ + { dg-end-multiline-output "" } */