aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-03-24 15:21:38 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-03-24 15:21:38 -0400
commit8a29084dea4f4d340f533a0c9f17aef0572218bc (patch)
tree74b5deb70db55b45ad927b3ccdb64fab326d1805
parent00e6c25ac8e7129a76deb68df0766d8736fc8442 (diff)
downloadgcc-8a29084dea4f4d340f533a0c9f17aef0572218bc.zip
gcc-8a29084dea4f4d340f533a0c9f17aef0572218bc.tar.gz
gcc-8a29084dea4f4d340f533a0c9f17aef0572218bc.tar.bz2
re PR c++/70386 (ICE with -Wall on valid code on x86_64-linux-gnu in verify_ctor_sanity, at cp/constexpr.c:2232)
PR c++/70386 * constexpr.c (cxx_eval_bare_aggregate): Handle PMFs. From-SVN: r234469
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/constexpr.c16
-rw-r--r--gcc/testsuite/g++.dg/expr/pmf-2.C18
3 files changed, 34 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6512cc5..45450ec 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2016-03-24 Jason Merrill <jason@redhat.com>
+ PR c++/70386
+ * constexpr.c (cxx_eval_bare_aggregate): Handle PMFs.
+
PR c++/70323
* constexpr.c (cxx_eval_call_expression): Don't cache result if
*overflow_p.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 2d30a84..8ea7111 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2268,8 +2268,19 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
bool changed = false;
gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));
+ tree type = TREE_TYPE (t);
- verify_ctor_sanity (ctx, TREE_TYPE (t));
+ constexpr_ctx new_ctx;
+ if (TYPE_PTRMEMFUNC_P (type))
+ {
+ /* We don't really need the ctx->ctor business for a PMF, but it's
+ simpler to use the same code. */
+ new_ctx = *ctx;
+ new_ctx.ctor = build_constructor (type, NULL);
+ new_ctx.object = NULL_TREE;
+ ctx = &new_ctx;
+ };
+ verify_ctor_sanity (ctx, type);
vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
vec_alloc (*p, vec_safe_length (v));
@@ -2280,7 +2291,6 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value)
{
tree orig_value = value;
- constexpr_ctx new_ctx;
init_subob_ctx (ctx, new_ctx, index, value);
if (new_ctx.ctor != ctx->ctor)
/* If we built a new CONSTRUCTOR, attach it now so that other
@@ -2334,7 +2344,7 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
CONSTRUCTOR_NO_IMPLICIT_ZERO (t) = false;
TREE_CONSTANT (t) = constant_p;
TREE_SIDE_EFFECTS (t) = side_effects_p;
- if (VECTOR_TYPE_P (TREE_TYPE (t)))
+ if (VECTOR_TYPE_P (type))
t = fold (t);
return t;
}
diff --git a/gcc/testsuite/g++.dg/expr/pmf-2.C b/gcc/testsuite/g++.dg/expr/pmf-2.C
new file mode 100644
index 0000000..79e36cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/pmf-2.C
@@ -0,0 +1,18 @@
+// PR c++/70386
+// { dg-options "-Wall" }
+
+struct A { void f () {} };
+struct B : public A {};
+struct C : public A {};
+struct D : public B, public C {};
+
+typedef void (C::*cp) ();
+typedef void (D::*dp) ();
+
+int
+main ()
+{
+ cp c = &A::f;
+ dp d = c;
+ return (cp () == d);
+}