diff options
author | Simon Martin <simon@nasilyan.com> | 2024-08-26 14:09:46 +0200 |
---|---|---|
committer | Simon Martin <simon@nasilyan.com> | 2024-08-27 21:48:49 +0200 |
commit | 02dff52c60e5b89d290147f142f655c7817154c2 (patch) | |
tree | 6f51054373899177bdc005408f1ab768b40634b2 /gcc | |
parent | 691f682fe24d07ff5854f1f53d81909320110c9c (diff) | |
download | gcc-02dff52c60e5b89d290147f142f655c7817154c2.zip gcc-02dff52c60e5b89d290147f142f655c7817154c2.tar.gz gcc-02dff52c60e5b89d290147f142f655c7817154c2.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/parser.cc | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/diagnostic/pr105483.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/error36.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tc1/dr147.C | 2 | ||||
-rw-r--r-- | 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 28ebf2b..a722641 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 0000000..b935bac --- /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 bf57a6b..73b550e 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 6b65649..ced18d1 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 4e1a4a8..0f0f68b 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 } +} |