https://gcc.gnu.org/g:64028d626a50410dbf29f252a78c7675b35751d6

commit r15-3043-g64028d626a50410dbf29f252a78c7675b35751d6
Author: Franciszek Witt <franek.w...@gmail.com>
Date:   Tue Aug 20 14:34:01 2024 +0200

    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.w...@gmail.com>

Diff:
---
 gcc/cp/parser.cc                           | 23 ++++++++++++++++++-----
 gcc/testsuite/g++.dg/cpp0x/initlist-err1.C | 11 +++++++++++
 gcc/testsuite/g++.dg/cpp0x/initlist-err2.C | 11 +++++++++++
 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 c9654cfff9d..c4388980348 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 00000000000..6ea8afb3273
--- /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 00000000000..227f519dc19
--- /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 00000000000..b77ec9bf4e9
--- /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" } 
+}

Reply via email to