===================================================================
@@ -4915,6 +4915,7 @@ potential_constant_expression_1 (tree t, bool want
case CONTINUE_STMT:
case REQUIRES_EXPR:
case STATIC_ASSERT:
+ case CLEANUP_STMT:
return true;
case AGGR_INIT_EXPR:
===================================================================
@@ -0,0 +1,16 @@
+// PR c++/77545
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template < typename T > struct A
+{
+ A ();
+ ~A ();
+ T t;
+};
+
+void f (A < int > a)
+{
+ for (auto x : (A < int >[]) { a })
+ ;
+}
Hi, I have been spending some time on this regression, where we ICE in potential_constant_expression_1 because CLEANUP_STMT is unhandled. Apparently the ICE started with https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=238559, where we started calling maybe_constant_value from cp_fully_fold, but now happens in the same way with that commit reverted too. The context of the ICE is the following: from store_init_value we call maybe_constant_init for a __for_range VAR_DECL as decl and a COMPUND_EXPR as value: <compound_expr 0x7ffff69bede8 type <reference_type 0x7ffff69de690 type <array_type 0x7ffff69d9f18 type <record_type 0x7ffff69d93f0 A> needs-constructing type_4 BLK size <integer_cst 0x7ffff68780d8 constant 32> unit size <integer_cst 0x7ffff68780f0 constant 4> align 32 symtab 0 alias set -1 canonical type 0x7ffff69d9f18 domain <integer_type 0x7ffff687fe70> pointer_to_this <pointer_type 0x7ffff69de1f8> reference_to_this <reference_type 0x7ffff69de5e8>> private unsigned DI size <integer_cst 0x7ffff6856e88 constant 64> unit size <integer_cst 0x7ffff6856ea0 constant 8> align 64 symtab 0 alias set -1 canonical type 0x7ffff69de690> side-effects arg 0 <statement_list 0x7ffff69d5e20 type <void_type 0x7ffff687d000 void type_6 VOID align 8 symtab 0 alias set -1 canonical type 0x7ffff687d000 pointer_to_this <pointer_type 0x7ffff687d150>> side-effects head 0x7ffff69d3e28 tail 0x7ffff69d3e40 stmts 0x7ffff69d5e60 0x7ffff6855bd0 stmt <cleanup_point_expr 0x7ffff69d5e60 type <void_type 0x7ffff687d000 void> side-effects tree_1 arg 0 <expr_stmt 0x7ffff69d5e40 type <void_type 0x7ffff687d000 void> side-effects arg 0 <init_expr 0x7ffff69bec30 type <record_type 0x7ffff69d93f0 A> side-effects arg 0 <array_ref 0x7ffff6863188 type <record_type 0x7ffff69d93f0 A> arg 0 <var_decl 0x7ffff69df090 D.2323> arg 1 <integer_cst 0x7ffff6856eb8 constant 0>> arg 1 <parm_decl 0x7ffff69d7300 a>> 77545.C:10:35 start: 77545.C:10:35 finish: 77545.C:10:35> 77545.C:10:35 start: 77545.C:10:35 finish: 77545.C:10:35> stmt <cleanup_stmt 0x7ffff6855bd0 type <void_type 0x7ffff687d000 void> side-effects static tree_1 arg 0 <statement_list 0x7ffff69d5f00 type <void_type 0x7ffff687d000 void> head (nil) tail (nil) stmts > arg 1 <call_expr 0x7ffff68631c0 type <void_type 0x7ffff687d000 void> side-effects nothrow fn <addr_expr 0x7ffff69d5ee0 type <pointer_type 0x7ffff69de0a8> constant arg 0 <function_decl 0x7ffff69db700 __comp_dtor >> arg 0 <nop_expr 0x7ffff69d5ea0 type <pointer_type 0x7ffff69d95e8> arg 0 <addr_expr 0x7ffff69d5e80 type <pointer_type 0x7ffff69d95e8> arg 0 <array_ref 0x7ffff6863188>>>> 77545.C:10:35 start: 77545.C:10:35 finish: 77545.C:10:35>> arg 1 <nop_expr 0x7ffff69e10a0 type <reference_type 0x7ffff69de690> arg 0 <addr_expr 0x7ffff69d5de0 type <pointer_type 0x7ffff69de1f8> arg 0 <var_decl 0x7ffff69df090 D.2323>>>> then, obviously, a bit later potential_constant_expression_1 stumbles into the CLEANUP_STMT among the statements in the STATEMENT_LIST we pass as ARG 0 of the COMPOUND_EXPR. I have been investigating how we build and handle CLEANUP_STMTs in constexpr.c (see in particular the comment at the beginning of build_data_member_initialization) and wondering if simply returning true for it from potential_constant_expression_1 wouldn't be correct... Certainly passes testing. Thanks for any feedback! Paolo. ///////////////////////////