diff mbox

[C++,Patch/RFC] PR 77545 ("[7 Regression] ICE on valid C++11 code: in potential_constant_expression_1..")

Message ID 54310d9f-afcf-020f-ed96-5c3e3fd00358@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Nov. 21, 2016, 3:38 p.m. UTC
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.

///////////////////////////
diff mbox

Patch

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 })
+    ;
+}