aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2019-02-23 01:19:38 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2019-02-23 01:19:38 +0000
commitc1753302087205dd9d5e9013c859623b261df060 (patch)
treea30ed4bf67b3c1071a65fbddd0096cd95d161cf3 /gcc
parent986e0e33f6e2349741ca5dafdeb167d215b28195 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/parser.c26
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/pr89390.C42
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 "" } */