On 11/19/25 1:57 PM, Jakub Jelinek wrote:
Hi!
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 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. */
In this testcase *maybe_range_for_decl is left NULL. Perhaps the existing
else if (maybe_range_for_decl)
{
if (*maybe_range_for_decl == NULL_TREE)
*maybe_range_for_decl = error_mark_node;
in the middle of the function should move to the end?
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2025-11-19 Jakub Jelinek <[email protected]>
PR c++/122465
* parser.cc (cp_hide_range_decl): Return early for NULL range_decl.
* g++.dg/cpp0x/pr122465.C: New test.
--- gcc/cp/parser.cc.jj 2025-11-17 15:23:03.940470500 +0100
+++ gcc/cp/parser.cc 2025-11-18 18:07:50.731806016 +0100
@@ -14911,7 +14911,7 @@ cp_hide_range_decl (tree *range_decl_p,
{
tree range_decl = *range_decl_p;
cp_decomp *decomp = NULL;
- if (range_decl == error_mark_node)
+ if (range_decl == error_mark_node || range_decl == NULL_TREE)
return decomp;
if (DECL_HAS_VALUE_EXPR_P (range_decl))
--- gcc/testsuite/g++.dg/cpp0x/pr122465.C.jj 2025-11-18 18:11:39.266570327
+0100
+++ gcc/testsuite/g++.dg/cpp0x/pr122465.C 2025-11-18 18:11:23.629791644
+0100
@@ -0,0 +1,11 @@
+// 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" }
+ ; // { dg-error "'begin' was not declared in this scope"
"" { target *-*-* } .-1 }
+} // { dg-error "'end' was not declared in this scope"
"" { target *-*-* } .-2 }
+ // { dg-error "assignment \\\(not initialization\\\) in
declaration" "" { target *-*-* } .-3 }
Jakub