On Mon, 2019-02-18 at 14:07 -1000, Jason Merrill wrote:
> On 2/18/19 12:50 PM, Jakub Jelinek wrote:
> > Hi!
> > 
> > On the following testcase we ICE because name is BIT_NOT_EXPR and
> > suggest_alternative_in_scoped_enum assumes it is called on
> > IDENTIFIER_NODE
> > only.
> > 
> > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-
> > linux, ok for
> > trunk?
> 
> OK.
> 
> > There is another issue, starting with 7.x we don't use sensible
> > location in
> > the diagnostics, 6.x emitted
> > 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'" }
> >     ^
> > but 7.x and later emits:
> > In function ‘void foo()’:
> > cc1plus: error: ‘~A’ is not a member of ‘A’
> > 
> > This patch doesn't deal with that, but would be nice to provide
> > location,
> > dunno if it is enough to just use location of ~, or if we need to
> > spend
> > memory and build ~A as combined range with caret on ~.

It should only cost memory if strlen(A) is > 30, since otherwise the
result will have caret==start and strlen() <= 31 and so hit the
optimized range representation.

> 
> I think having a range for a destructor id-expression would be
> appropriate.
> 
> Jason

How about something like this? (on top of Jakub's patch)

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).

gcc/cp/ChangeLog:
        PR c++/89390
        * parser.c (cp_parser_unqualified_id): Capture locations for
        destructors.

gcc/testsuite/ChangeLog:
        PR c++/89390
        * g++.dg/diagnostic/pr89390.C: Update expected location of error.
        Add testcase within namespace.
---
 gcc/cp/parser.c                           |  9 ++++++++-
 gcc/testsuite/g++.dg/diagnostic/pr89390.C | 10 +++++++++-
 2 files changed, 17 insertions(+), 2 deletions(-)

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'" }
 }
-- 
1.8.5.3

Reply via email to