On Tue, Sep 25, 2018 at 11:07:19AM -0400, Jason Merrill wrote:
> > You're right.  So like this (only look through COMPONENT_REFs where the
> > FIELD_DECL is DECL_FIELD_IS_BASE)?
> > Only checked
> > make check-c++-all RUNTESTFLAGS="dg.exp='constexpr-virt* pr87398*'"
> > so far, but it also fixes the PR87425 testcase and doesn't regress anything.
> 
> Looks good.

Thanks, will bootstrap/regtest it now.  I also took your testcase and turned it 
into
something that ICEd without this patch too, is that testcase also ok
(constexpr-virtual11.C)?

2018-09-25  Jakub Jelinek  <ja...@redhat.com>

        PR c++/87398
        * constexpr.c (cxx_eval_constant_expression) <case OBJ_TYPE_REF>: Only
        look through COMPONENT_REFs with DECL_FIELD_IS_BASE FIELD_DECLs.

        * g++.dg/other/pr87398.C: New test.
        * g++.dg/cpp2a/constexpr-virtual10.C: New test.
        * g++.dg/cpp2a/constexpr-virtual11.C: New test.

--- gcc/cp/constexpr.c.jj       2018-09-25 15:14:36.335386401 +0200
+++ gcc/cp/constexpr.c  2018-09-25 16:50:38.085334475 +0200
@@ -4812,7 +4812,8 @@ cxx_eval_constant_expression (const cons
            return t;
          }
        obj = TREE_OPERAND (obj, 0);
-       while (handled_component_p (obj))
+       while (TREE_CODE (obj) == COMPONENT_REF
+              && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1)))
          obj = TREE_OPERAND (obj, 0);
        tree objtype = TREE_TYPE (obj);
        /* Find the function decl in the virtual functions list.  TOKEN is
--- gcc/testsuite/g++.dg/other/pr87398.C.jj     2018-09-25 16:49:40.458304980 
+0200
+++ gcc/testsuite/g++.dg/other/pr87398.C        2018-09-25 16:49:40.458304980 
+0200
@@ -0,0 +1,12 @@
+// PR c++/87398
+// { dg-do compile }
+
+struct A { virtual int foo (); };
+
+int
+bar (int x)
+{
+  A e[5][2];
+  int f = e[4][x].foo ();
+  return f;
+}
--- gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C.jj 2018-09-25 
16:49:40.458304980 +0200
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C    2018-09-25 
16:49:40.458304980 +0200
@@ -0,0 +1,18 @@
+// P1064R0
+// { dg-do compile }
+// { dg-options "-std=c++2a" }
+
+struct X
+{
+  constexpr virtual int f() const { return 1; };
+};
+
+struct Y : public X
+{
+  constexpr virtual int f() const { return 2; };
+};
+
+constexpr X a[2][1][3];
+constexpr Y b[3][12];
+static_assert (a[1][0][1].f() == 1);
+static_assert (b[2][11].f() == 2);
--- gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C.jj 2018-09-01 
11:09:41.506153390 +0200
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C    2018-09-25 
17:11:30.563244029 +0200
@@ -0,0 +1,26 @@
+// P1064R0
+// { dg-do compile }
+// { dg-options "-std=c++2a" }
+
+struct A
+{
+  constexpr virtual int f () const { return 1; }
+};
+
+struct B : public A
+{
+  constexpr virtual int f () const { return 2; }
+};
+
+struct C
+{
+  A a;
+  B b;
+};
+
+constexpr C c;
+constexpr const A &d = c.a;
+constexpr const A &e = c.b;
+constexpr const B &f = c.b;
+static_assert (c.a.f () == 1 && c.b.f () == 2);
+static_assert (d.f () == 1 && e.f () == 2 && f.f () == 2);


        Jakub

Reply via email to