From: Jason Merrill Date: Thu, 24 Mar 2016 19:21:38 +0000 (-0400) Subject: re PR c++/70386 (ICE with -Wall on valid code on x86_64-linux-gnu in verify_ctor_sani... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8a29084dea4f4d340f533a0c9f17aef0572218bc;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6512cc5b0a8..45450ec2f06 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2016-03-24 Jason Merrill + 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 2d30a841279..8ea71113d99 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 *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 **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 00000000000..79e36cf78c0 --- /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); +}