diff options
author | David Malcolm <dmalcolm@redhat.com> | 2019-02-23 01:19:38 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2019-02-23 01:19:38 +0000 |
commit | c1753302087205dd9d5e9013c859623b261df060 (patch) | |
tree | a30ed4bf67b3c1071a65fbddd0096cd95d161cf3 /gcc | |
parent | 986e0e33f6e2349741ca5dafdeb167d215b28195 (diff) | |
download | gcc-c1753302087205dd9d5e9013c859623b261df060.zip gcc-c1753302087205dd9d5e9013c859623b261df060.tar.gz gcc-c1753302087205dd9d5e9013c859623b261df060.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/diagnostic/pr89390.C | 42 |
4 files changed, 71 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8381391..2a5056a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-02-22 David Malcolm <dmalcolm@redhat.com> + + PR c++/89390 + * parser.c (cp_parser_unqualified_id): Capture and use locations + for destructors. + 2019-02-22 Marek Polacek <polacek@redhat.com> PR c++/89420 - ICE with CAST_EXPR in explicit-specifier. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 545047c..e976008 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 4d3d307..4751104 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-02-22 David Malcolm <dmalcolm@redhat.com> + + 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 <paolo.carlini@oracle.com> PR c++/84676 diff --git a/gcc/testsuite/g++.dg/diagnostic/pr89390.C b/gcc/testsuite/g++.dg/diagnostic/pr89390.C index 8dae827..2e8c95a 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 "" } */ |