re PR c++/70386 (ICE with -Wall on valid code on x86_64-linux-gnu in verify_ctor_sani...
authorJason Merrill <jason@redhat.com>
Thu, 24 Mar 2016 19:21:38 +0000 (15:21 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 24 Mar 2016 19:21:38 +0000 (15:21 -0400)
PR c++/70386

* constexpr.c (cxx_eval_bare_aggregate): Handle PMFs.

From-SVN: r234469

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/expr/pmf-2.C [new file with mode: 0644]

index 6512cc5b0a8a00098419ab7524284941fead05ca..45450ec2f06e68b7b8947573b5e223ab722a9712 100644 (file)
@@ -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.
index 2d30a84127938c150418fc0c73d74fbb789823b1..8ea71113d9991ec10e41187749dcf5c2561ee350 100644 (file)
@@ -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 (file)
index 0000000..79e36cf
--- /dev/null
@@ -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);
+}