aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi11.C23
3 files changed, 32 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 774c36e..5029f83 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2015-05-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/66320
+ * constexpr.c (cxx_eval_constant_expression): Treat a placeholder
+ with the wrong type as non-constant.
+
2015-05-27 Jason Merrill <jason@redhat.com>
* decl.c (check_redeclaration_exception_specification): Depend on
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index f35ec1e..f343ea7 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3458,7 +3458,9 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
break;
case PLACEHOLDER_EXPR:
- if (!ctx || !ctx->ctor || (lval && !ctx->object))
+ if (!ctx || !ctx->ctor || (lval && !ctx->object)
+ || !(same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (t), TREE_TYPE (ctx->ctor))))
{
/* A placeholder without a referent. We can get here when
checking whether NSDMIs are noexcept, or in massage_init_elt;
@@ -3473,8 +3475,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
use ctx->object unconditionally, but using ctx->ctor when we
can is a minor optimization. */
tree ctor = lval ? ctx->object : ctx->ctor;
- gcc_assert (same_type_ignoring_top_level_qualifiers_p
- (TREE_TYPE (t), TREE_TYPE (ctor)));
return cxx_eval_constant_expression
(ctx, ctor, lval,
non_constant_p, overflow_p);
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi11.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi11.C
new file mode 100644
index 0000000..29942b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi11.C
@@ -0,0 +1,23 @@
+// PR c++/66320
+// { dg-do compile { target c++11 } }
+
+class A
+{
+ virtual int m_fn1 ();
+};
+class B
+{
+public:
+ B (int);
+};
+class D : B
+{
+ struct C
+ {
+ A a;
+ A b = a;
+ };
+ D (int *);
+ C _channels;
+};
+D::D (int *) : B (0) {}