We need to handle TRY_BLOCK and TRY_FINALLY_EXPR in the constexpr code.
Tested x86_64-pc-linux-gnu, applying to trunk and 5.
commit 8f851dc2420532bda205410a99bcd672090cfe6a Author: Jason Merrill <ja...@redhat.com> Date: Wed Jun 17 18:31:02 2015 -0400 PR c++/66001 * constexpr.c (cxx_eval_constant_expression): Handle TRY_BLOCK and TRY_FINALLY_EXPR. (potential_constant_expression_1): Likewise. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index f28b918..21a68b1 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3189,6 +3189,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case NON_LVALUE_EXPR: case TRY_CATCH_EXPR: + case TRY_BLOCK: case CLEANUP_POINT_EXPR: case MUST_NOT_THROW_EXPR: case EXPR_STMT: @@ -3199,6 +3200,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, jump_target); break; + case TRY_FINALLY_EXPR: + r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, + non_constant_p, overflow_p, + jump_target); + if (!*non_constant_p) + /* Also evaluate the cleanup. */ + cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), lval, + non_constant_p, overflow_p, + jump_target); + break; + /* These differ from cxx_eval_unary_expression in that this doesn't check for a constant operand or result; an address can be constant without its operand being, and vice versa. */ @@ -4273,6 +4285,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case CLEANUP_POINT_EXPR: case MUST_NOT_THROW_EXPR: case TRY_CATCH_EXPR: + case TRY_BLOCK: case EH_SPEC_BLOCK: case EXPR_STMT: case PAREN_EXPR: @@ -4418,6 +4431,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case MEMBER_REF: case DOTSTAR_EXPR: case MEM_REF: + case TRY_FINALLY_EXPR: binary: for (i = 0; i < 2; ++i) if (!RECUR (TREE_OPERAND (t, i), want_rval)) diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi12.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi12.C new file mode 100644 index 0000000..11618a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi12.C @@ -0,0 +1,16 @@ +// PR c++/66001 +// { dg-do compile { target c++11 } } + +#include <initializer_list> + +struct dt + { dt() {} ~ dt() {} }; + +struct x { + std::initializer_list< dt > f = { {} }; +} cx; + +struct x2 { + struct dt { ~ dt() {} } + const & m = {}; +} cx2;