OK.
On Tue, Nov 20, 2018 at 3:51 PM Jakub Jelinek <ja...@redhat.com> wrote:
>
> Hi!
>
> The comment in OBJ_TYPE_REF handling code correctly says that we are
> looking for x.D.2103.D.2094, but it is important that x is not an
> INDIRECT_REF or something similar as in the following testcase - we can't
> really devirtualize in that case because we really don't know what it points
> to.  The following patch ensures that the argument got evaluated to address
> of some field of (ultimately) a decl, which is all we should get during
> valid constexpr evaluation.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2018-11-20  Jakub Jelinek  <ja...@redhat.com>
>
>         PR c++/88110
>         * constexpr.c (cxx_eval_constant_expression) <case OBJ_TYPE_REF>: Punt
>         if get_base_address of ADDR_EXPR operand is not a DECL_P.
>
>         * g++.dg/cpp2a/constexpr-virtual13.C: New test.
>
> --- gcc/cp/constexpr.c.jj       2018-11-19 14:24:49.000000000 +0100
> +++ gcc/cp/constexpr.c  2018-11-20 15:03:26.968152935 +0100
> @@ -4815,7 +4815,8 @@ cxx_eval_constant_expression (const cons
>         obj = cxx_eval_constant_expression (ctx, obj, lval, non_constant_p,
>                                             overflow_p);
>         /* We expect something in the form of &x.D.2103.D.2094; get x. */
> -       if (TREE_CODE (obj) != ADDR_EXPR)
> +       if (TREE_CODE (obj) != ADDR_EXPR
> +           || !DECL_P (get_base_address (TREE_OPERAND (obj, 0))))
>           {
>             if (!ctx->quiet)
>               error_at (cp_expr_loc_or_loc (t, input_location),
> --- gcc/testsuite/g++.dg/cpp2a/constexpr-virtual13.C.jj 2018-11-20 
> 15:07:17.558386765 +0100
> +++ gcc/testsuite/g++.dg/cpp2a/constexpr-virtual13.C    2018-11-20 
> 15:05:30.188140420 +0100
> @@ -0,0 +1,20 @@
> +// PR c++/88110
> +// { dg-do compile }
> +
> +struct A {
> +  virtual int foo () const = 0;
> +};
> +struct B {
> +  virtual int bar () const = 0;
> +  virtual int baz () const = 0;
> +};
> +struct C : public A { };
> +struct D : public C { };
> +struct E : public D, public B { };
> +
> +void
> +qux (const E *x)
> +{
> +  if (x->baz ())
> +    ;
> +}
>
>         Jakub

Reply via email to