On Thu, Nov 20, 2025 at 10:46:21AM +0530, Jason Merrill wrote:
> > The following testcase shows that range_decl in cp_hide_range_decl is
> > sometimes also NULL_TREE and not just error_mark_node, and the function
> > IMHO should treat both the same, not try to hide anything in that case
> > because it doesn't know what should be hidden.  This ICEs during
> > error recovery since something like cp_hide_range_decl has been introduced
> > (earlier it wasn't called that way).
> 
> This seems like cp_parser_simple_declaration is violating its comment:

If the intent was a decl or error_mark_node as the comment says, then
it wouldn't start with
  if (maybe_range_for_decl)
    *maybe_range_for_decl = NULL_TREE;
Furthermore, I think it would be really weird to set *maybe_range_for_decl
to error_mark_node in the non-erroneous cases, the name of the argument
includes maybe_ prefix.

I think it is just fine to set *maybe_range_for_decl to error_mark_node
in the erroneous cases, basically make sure that if it is followed by
CPP_COLON (i.e. when cp_parser_init_statement is going to return true)
then it will never be NULL.

Here is a patch which does that, so far tested with
GXX_TESTSUITE_STDS=98,11,14,17,20,23,26 make -j32 -k check-g++ check-obj-c++
in gcc/ and libstdc++-v3 make check, ok for trunk if it passes full
bootstrap/regtest?

2025-11-20  Jakub Jelinek  <[email protected]>

        PR c++/122465
        * parser.cc (cp_parser_simple_declaration): Adjust function comment.
        Set *maybe_range_for_decl to error_mark_node instead of keeping it
        NULL_TREE in error cases or when followed by CPP_COLON.

        * g++.dg/cpp0x/pr122465.C: New test.

--- gcc/cp/parser.cc.jj 2025-11-20 11:19:13.583211387 +0100
+++ gcc/cp/parser.cc    2025-11-20 12:02:19.051259722 +0100
@@ -17032,8 +17032,9 @@ cp_parser_block_declaration (cp_parser *
 
    If MAYBE_RANGE_FOR_DECL is not NULL, the pointed tree will be set to the
    parsed declaration if it is an uninitialized single declarator not followed
-   by a `;', or to error_mark_node otherwise. Either way, the trailing `;',
-   if present, will not be consumed.  */
+   by a `;', or to NULL_TREE when not followed by `:' or to error_mark_node
+   otherwise.  Either way, the trailing `;', if present, will not be
+   consumed.  */
 
 static void
 cp_parser_simple_declaration (cp_parser* parser,
@@ -17085,6 +17086,9 @@ cp_parser_simple_declaration (cp_parser*
       && !decl_specifiers.any_specifiers_p)
     {
       cp_parser_error (parser, "expected declaration");
+    error_out:
+      if (maybe_range_for_decl && *maybe_range_for_decl == NULL_TREE)
+       *maybe_range_for_decl = error_mark_node;
       goto done;
     }
 
@@ -17101,7 +17105,7 @@ cp_parser_simple_declaration (cp_parser*
         looking at a declaration.  */
       cp_parser_commit_to_tentative_parse (parser);
       /* Give up.  */
-      goto done;
+      goto error_out;
     }
 
   cp_parser_maybe_commit_to_declaration (parser, &decl_specifiers);
@@ -17126,11 +17130,7 @@ cp_parser_simple_declaration (cp_parser*
        if (token->type == CPP_SEMICOLON)
          goto finish;
        else if (maybe_range_for_decl)
-         {
-           if (*maybe_range_for_decl == NULL_TREE)
-             *maybe_range_for_decl = error_mark_node;
-           goto finish;
-         }
+         goto finish;
        /* Anything else is an error.  */
        else
          {
@@ -17209,7 +17209,7 @@ cp_parser_simple_declaration (cp_parser*
         statement is treated as a declaration-statement until proven
         otherwise.)  */
       if (cp_parser_error_occurred (parser))
-       goto done;
+       goto error_out;
 
       if (auto_specifier_p && cxx_dialect >= cxx14)
        {
@@ -17347,6 +17347,8 @@ cp_parser_simple_declaration (cp_parser*
       if (comma_loc != UNKNOWN_LOCATION)
        error_at (comma_loc,
                  "multiple declarations in range-based %<for%> loop");
+      if (*maybe_range_for_decl == NULL_TREE)
+       *maybe_range_for_decl = error_mark_node;
     }
 
  done:
--- gcc/testsuite/g++.dg/cpp0x/pr122465.C.jj    2025-11-20 11:19:04.978706617 
+0100
+++ gcc/testsuite/g++.dg/cpp0x/pr122465.C       2025-11-20 12:06:11.387942293 
+0100
@@ -0,0 +1,10 @@
+// PR c++/122465
+// { dg-do compile { target c++11 } }
+
+void
+foo ()
+{    
+  int x = 0;
+  for (const T i = { i } : x)  // { dg-error "'T' does not name a type" }
+    ;
+}


        Jakub

Reply via email to