diff options
author | Franciszek Witt <franek.witt@gmail.com> | 2024-08-20 14:34:01 +0200 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2024-08-20 11:21:28 -0400 |
commit | 64028d626a50410dbf29f252a78c7675b35751d6 (patch) | |
tree | f18a41be058f7546ad4558f5e05d93733889aca8 | |
parent | 81bf84cf6b1b16609a59ceac5166c3846bba26cd (diff) | |
download | gcc-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.cc | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-err1.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-err2.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-err3.C | 11 |
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" } +} |