aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2023-10-17 16:11:11 -0400
committerMarek Polacek <polacek@redhat.com>2023-10-17 17:44:59 -0400
commit1fbb7d75abbb050f790d8b43422602ee4b152608 (patch)
treeb3745431a0e2b6322e7722fed316325e0b474349
parent765c3b8f82d50961008c214ac2113f35e7532aa9 (diff)
downloadgcc-1fbb7d75abbb050f790d8b43422602ee4b152608.zip
gcc-1fbb7d75abbb050f790d8b43422602ee4b152608.tar.gz
gcc-1fbb7d75abbb050f790d8b43422602ee4b152608.tar.bz2
c++: accepts-invalid with =delete("") [PR111840]
r6-2367 added a DECL_INITIAL check to cp_parser_simple_declaration so that we don't emit multiple errors in g++.dg/parse/error57.C. But that means we don't diagnose int f1() = delete("george_crumb"); anymore, because fn decls often have error_mark_node in their DECL_INITIAL. (The code may be allowed one day via https://wg21.link/P2573R0.) I was hoping I could use cp_parser_error_occurred but that would regress error57.C. PR c++/111840 gcc/cp/ChangeLog: * parser.cc (cp_parser_simple_declaration): Do cp_parser_error for FUNCTION_DECLs. gcc/testsuite/ChangeLog: * g++.dg/parse/error65.C: New test.
-rw-r--r--gcc/cp/parser.cc14
-rw-r--r--gcc/testsuite/g++.dg/parse/error65.C10
2 files changed, 17 insertions, 7 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 59b9852..57b62fb 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -15669,6 +15669,7 @@ cp_parser_simple_declaration (cp_parser* parser,
maybe_range_for_decl,
&init_loc,
&auto_result);
+ const bool fndecl_p = TREE_CODE (decl) == FUNCTION_DECL;
/* If an error occurred while parsing tentatively, exit quickly.
(That usually happens when in the body of a function; each
statement is treated as a declaration-statement until proven
@@ -15682,16 +15683,13 @@ cp_parser_simple_declaration (cp_parser* parser,
init-declarator, they shall all form declarations of
variables. */
if (auto_function_declaration == NULL_TREE)
- auto_function_declaration
- = TREE_CODE (decl) == FUNCTION_DECL ? decl : error_mark_node;
- else if (TREE_CODE (decl) == FUNCTION_DECL
- || auto_function_declaration != error_mark_node)
+ auto_function_declaration = fndecl_p ? decl : error_mark_node;
+ else if (fndecl_p || auto_function_declaration != error_mark_node)
{
error_at (decl_specifiers.locations[ds_type_spec],
"non-variable %qD in declaration with more than one "
"declarator with placeholder type",
- TREE_CODE (decl) == FUNCTION_DECL
- ? decl : auto_function_declaration);
+ fndecl_p ? decl : auto_function_declaration);
auto_function_declaration = error_mark_node;
}
}
@@ -15763,7 +15761,9 @@ cp_parser_simple_declaration (cp_parser* parser,
/* If we have already issued an error message we don't need
to issue another one. */
if ((decl != error_mark_node
- && DECL_INITIAL (decl) != error_mark_node)
+ /* grokfndecl sets DECL_INITIAL to error_mark_node for
+ functions. */
+ && (fndecl_p || DECL_INITIAL (decl) != error_mark_node))
|| cp_parser_uncommitted_to_tentative_parse_p (parser))
cp_parser_error (parser, "expected %<,%> or %<;%>");
/* Skip tokens until we reach the end of the statement. */
diff --git a/gcc/testsuite/g++.dg/parse/error65.C b/gcc/testsuite/g++.dg/parse/error65.C
new file mode 100644
index 0000000..d9e0a4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/error65.C
@@ -0,0 +1,10 @@
+// PR c++/111840
+// { dg-do compile { target c++11 } }
+
+// NB: =delete("reason") may be allowed via P2573.
+int f1() = delete("should have a reason"); // { dg-error "expected" }
+int f2() = delete[""]; // { dg-error "expected" }
+int f3() = delete{""}; // { dg-error "expected" }
+int f4() = delete""; // { dg-error "expected" }
+int f5() = delete[{'a'""; // { dg-error "expected" }
+int i = f5();