aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranciszek Witt <franek.witt@gmail.com>2024-08-20 14:34:01 +0200
committerJason Merrill <jason@redhat.com>2024-08-20 11:21:28 -0400
commit64028d626a50410dbf29f252a78c7675b35751d6 (patch)
treef18a41be058f7546ad4558f5e05d93733889aca8
parent81bf84cf6b1b16609a59ceac5166c3846bba26cd (diff)
downloadgcc-64028d626a50410dbf29f252a78c7675b35751d6.zip
gcc-64028d626a50410dbf29f252a78c7675b35751d6.tar.gz
gcc-64028d626a50410dbf29f252a78c7675b35751d6.tar.bz2
c++: Improve errors parsing a braced list [PR101232]
PR c++/101232 gcc/cp/ChangeLog: * parser.cc (cp_parser_postfix_expression): Commit to the parse in case we know its either a cast or invalid syntax. (cp_parser_braced_list): Add a heuristic to inform about missing comma or operator. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-err1.C: New test. * g++.dg/cpp0x/initlist-err2.C: New test. * g++.dg/cpp0x/initlist-err3.C: New test. Signed-off-by: Franciszek Witt <franek.witt@gmail.com>
-rw-r--r--gcc/cp/parser.cc23
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-err1.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-err2.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-err3.C11
4 files changed, 51 insertions, 5 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index c9654cf..c438898 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -7878,8 +7878,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
--parser->prevent_constrained_type_specifiers;
/* Parse the cast itself. */
if (!cp_parser_error_occurred (parser))
- postfix_expression
- = cp_parser_functional_cast (parser, type);
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ /* This can only be a cast. */
+ cp_parser_commit_to_topmost_tentative_parse (parser);
+ postfix_expression
+ = cp_parser_functional_cast (parser, type);
+ }
/* If that worked, we're done. */
if (cp_parser_parse_definitely (parser))
break;
@@ -26372,7 +26377,7 @@ cp_parser_braced_list (cp_parser *parser, bool *non_constant_p /*=nullptr*/)
/* Consume the `{' token. */
matching_braces braces;
- braces.require_open (parser);
+ bool found_opening_brace = braces.require_open (parser);
/* Create a CONSTRUCTOR to represent the braced-initializer. */
initializer = make_node (CONSTRUCTOR);
/* If it's not a `}', then there is a non-trivial initializer. */
@@ -26390,8 +26395,16 @@ cp_parser_braced_list (cp_parser *parser, bool *non_constant_p /*=nullptr*/)
else if (non_constant_p)
*non_constant_p = false;
/* Now, there should be a trailing `}'. */
- location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
- braces.require_close (parser);
+ cp_token * token = cp_lexer_peek_token (parser->lexer);
+ location_t finish_loc = token->location;
+ /* The part with CPP_SEMICOLON is just a heuristic. */
+ if (!braces.require_close (parser) && token->type != CPP_SEMICOLON
+ && found_opening_brace && cp_parser_skip_to_closing_brace (parser))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ inform (finish_loc,
+ "probably missing a comma or an operator before");
+ }
TREE_TYPE (initializer) = init_list_type_node;
recompute_constructor_flags (initializer);
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-err1.C b/gcc/testsuite/g++.dg/cpp0x/initlist-err1.C
new file mode 100644
index 0000000..6ea8afb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-err1.C
@@ -0,0 +1,11 @@
+// PR c++/101232
+// { dg-do compile { target c++11 } }
+
+struct X {
+ int a;
+ int b;
+};
+
+void f() {
+ auto x = X{ 1, 2; }; // { dg-error "21:" }
+} // { dg-prune-output "expected declaration" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-err2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-err2.C
new file mode 100644
index 0000000..227f519
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-err2.C
@@ -0,0 +1,11 @@
+// PR c++/101232
+// { dg-do compile { target c++11 } }
+
+struct X {
+ int a;
+ int b;
+};
+
+void f() {
+ auto x = X{ 1 2 }; // { dg-error "19:.*probably" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-err3.C b/gcc/testsuite/g++.dg/cpp0x/initlist-err3.C
new file mode 100644
index 0000000..b77ec9b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-err3.C
@@ -0,0 +1,11 @@
+// PR c++/101232
+// { dg-do compile { target c++11 } }
+
+struct X {
+ int a;
+ int b;
+};
+
+void f() {
+ auto x = X{ 1, {2 }; // { dg-error "expected.*before" }
+}