aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-06-18 10:55:23 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-06-18 10:55:23 -0400
commit769430b29ce63353fa10f5122e406578eaea3328 (patch)
tree06a7f084677619ac8ab0087fe06bf716fe115ce9 /gcc
parent7e92772131fbcdc934c6ebf5cce8c8e3053554a7 (diff)
downloadgcc-769430b29ce63353fa10f5122e406578eaea3328.zip
gcc-769430b29ce63353fa10f5122e406578eaea3328.tar.gz
gcc-769430b29ce63353fa10f5122e406578eaea3328.tar.bz2
re PR c++/66001 (ICE when NSDMI in a literal class uses a destructor)
PR c++/66001 * constexpr.c (cxx_eval_constant_expression): Handle TRY_BLOCK and TRY_FINALLY_EXPR. (potential_constant_expression_1): Likewise. From-SVN: r224620
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/constexpr.c17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi12.C16
3 files changed, 40 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 153b3c4..eb8d97a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
2015-06-17 Jason Merrill <jason@redhat.com>
+ PR c++/66001
+ * constexpr.c (cxx_eval_constant_expression): Handle TRY_BLOCK and
+ TRY_FINALLY_EXPR.
+ (potential_constant_expression_1): Likewise.
+
+2015-06-17 Jason Merrill <jason@redhat.com>
+
PR c++/66515
* call.c (implicit_conversion): Call reshape_init here, early.
(build_aggr_conv): Not here.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index a52c96f..5688588 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3182,6 +3182,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:
@@ -3192,6 +3193,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), true,
+ 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. */
@@ -4266,6 +4278,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:
@@ -4275,6 +4288,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
case RETURN_EXPR:
return RECUR (TREE_OPERAND (t, 0), want_rval);
+ case TRY_FINALLY_EXPR:
+ return (RECUR (TREE_OPERAND (t, 0), want_rval)
+ && RECUR (TREE_OPERAND (t, 1), any));
+
case SCOPE_REF:
return RECUR (TREE_OPERAND (t, 1), 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;