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.
///////////////////////////
Index: cp/constexpr.c
===================================================================
--- cp/constexpr.c (revision 242657)
+++ cp/constexpr.c (working copy)
@@ -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:
Index: testsuite/g++.dg/cpp0x/range-for32.C
===================================================================
--- testsuite/g++.dg/cpp0x/range-for32.C (revision 0)
+++ testsuite/g++.dg/cpp0x/range-for32.C (working copy)
@@ -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 })
+ ;
+}