https://gcc.gnu.org/g:02dff52c60e5b89d290147f142f655c7817154c2

commit r15-3232-g02dff52c60e5b89d290147f142f655c7817154c2
Author: Simon Martin <si...@nasilyan.com>
Date:   Mon Aug 26 14:09:46 2024 +0200

    c++: Don't show constructor internal name in error message [PR105483]
    
    We mention 'X::__ct' instead of 'X::X' in the "names the constructor,
    not the type" error for this invalid code:
    
    === cut here ===
    struct X {};
    void g () {
      X::X x;
    }
    === cut here ===
    
    The problem is that we use %<%T::%D%> to build the error message, while
    %qE does exactly what we need since we have DECL_CONSTRUCTOR_P. This is
    what this patch does.
    
    It also skips until the end of the statement and returns error_mark_node
    for this and the preceding if block, to avoid emitting extra (useless)
    errors.
    
            PR c++/105483
    
    gcc/cp/ChangeLog:
    
            * parser.cc (cp_parser_expression_statement): Use %qE instead of
            incorrect %<%T::%D%>. Skip to end of statement and return
            error_mark_node in case of error.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/parse/error36.C: Adjust test expectation.
            * g++.dg/tc1/dr147.C: Likewise.
            * g++.old-deja/g++.other/typename1.C: Likewise.
            * g++.dg/diagnostic/pr105483.C: New test.

Diff:
---
 gcc/cp/parser.cc                                 | 14 +++++++++-----
 gcc/testsuite/g++.dg/diagnostic/pr105483.C       |  7 +++++++
 gcc/testsuite/g++.dg/parse/error36.C             |  4 ++--
 gcc/testsuite/g++.dg/tc1/dr147.C                 |  2 +-
 gcc/testsuite/g++.old-deja/g++.other/typename1.C |  2 +-
 5 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 28ebf2beb60a..a722641be347 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -13232,18 +13232,22 @@ cp_parser_expression_statement (cp_parser* parser, 
tree in_statement_expr)
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
       && !cp_parser_uncommitted_to_tentative_parse_p (parser))
     {
+      bool has_errored = true;
       if (TREE_CODE (statement) == SCOPE_REF)
        error_at (token->location, "need %<typename%> before %qE because "
                  "%qT is a dependent scope",
                  statement, TREE_OPERAND (statement, 0));
       else if (is_overloaded_fn (statement)
               && DECL_CONSTRUCTOR_P (get_first_fn (statement)))
+       /* A::A a; */
+       error_at (token->location, "%qE names the constructor, not the type",
+                 get_first_fn (statement));
+      else
+       has_errored = false;
+      if (has_errored)
        {
-         /* A::A a; */
-         tree fn = get_first_fn (statement);
-         error_at (token->location,
-                   "%<%T::%D%> names the constructor, not the type",
-                   DECL_CONTEXT (fn), DECL_NAME (fn));
+         cp_parser_skip_to_end_of_statement (parser);
+         return error_mark_node;
        }
     }
 
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr105483.C 
b/gcc/testsuite/g++.dg/diagnostic/pr105483.C
new file mode 100644
index 000000000000..b935bacea11b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/pr105483.C
@@ -0,0 +1,7 @@
+// PR c++/105483
+// { dg-do compile }
+
+struct X { };
+void g () {
+  X::X x; // { dg-error "'X::X' names the constructor" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/error36.C 
b/gcc/testsuite/g++.dg/parse/error36.C
index bf57a6b68ce8..73b550e3f2ad 100644
--- a/gcc/testsuite/g++.dg/parse/error36.C
+++ b/gcc/testsuite/g++.dg/parse/error36.C
@@ -12,7 +12,7 @@ void f(T t)
 {
   typedef A<T>::foo type;      // { dg-error "typename" }
   A<T>::bar b;                 // { dg-error "typename" "typename" }
-} // { dg-error "expected ';'" "expected" { target *-*-* } .-1 }
+}
 
 // PR c++/36353
 template <class T> struct B
@@ -20,7 +20,7 @@ template <class T> struct B
   void f()
   {
     A<T>::baz z;               // { dg-error "typename" "typename" }
-  } // { dg-error "expected ';'" "expected" { target *-*-* } .-1 }
+  }
 };
 
 // PR c++/40738
diff --git a/gcc/testsuite/g++.dg/tc1/dr147.C b/gcc/testsuite/g++.dg/tc1/dr147.C
index 6b656491e816..ced18d1879cc 100644
--- a/gcc/testsuite/g++.dg/tc1/dr147.C
+++ b/gcc/testsuite/g++.dg/tc1/dr147.C
@@ -21,7 +21,7 @@ void A::f()
 void f()
 {
   A::A a; // { dg-error "constructor" "constructor" }
-} // { dg-error "" "error cascade" { target *-*-* } .-1 } error cascade
+}
 }
 
 namespace N2 {
diff --git a/gcc/testsuite/g++.old-deja/g++.other/typename1.C 
b/gcc/testsuite/g++.old-deja/g++.other/typename1.C
index 4e1a4a834ddd..0f0f68b1cee2 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/typename1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/typename1.C
@@ -14,4 +14,4 @@ template<class T>
 void f()
 {
   Vector<T>::iterator i = 0; // { dg-error "typename" "typename" } missing 
typename
-} // { dg-error "expected" "expected" { target *-*-* } .-1 }
+}

Reply via email to