re PR c++/87398 (g++ ICE on valid code: tree check: expected record_type or union_typ...
authorJakub Jelinek <jakub@redhat.com>
Tue, 25 Sep 2018 16:40:57 +0000 (18:40 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 25 Sep 2018 16:40:57 +0000 (18:40 +0200)
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.

From-SVN: r264580

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/pr87398.C [new file with mode: 0644]

index 9ce845d20ac1311bae3bcc2a672373010b1580c3..672626c27d981f249e0301124fba6c00709d581c 100644 (file)
@@ -1,3 +1,9 @@
+2018-09-25  Jakub Jelinek  <jakub@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.
+
 2018-09-25  Martin Liska  <mliska@suse.cz>
 
        * name-lookup.c (namespace_scope_ht_size): Remove
index 08d00e859d8773d33830ae722d2f88167e80f792..403edda8c47b796412888892bc3a0df8f35b62b3 100644 (file)
@@ -4812,7 +4812,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
            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
index 24bf238e0f6cd4e2e739806f1cc5bddb44f2e7ea..68f1c3d9a2b9c876160b90734fadc2ca2af2090c 100644 (file)
@@ -1,3 +1,10 @@
+2018-09-25  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/87398
+       * g++.dg/other/pr87398.C: New test.
+       * g++.dg/cpp2a/constexpr-virtual10.C: New test.
+       * g++.dg/cpp2a/constexpr-virtual11.C: New test.
+
 2018-09-25  Martin Jambor  <mjambor@suse.cz>
 
        PR testsuite/87339
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C
new file mode 100644 (file)
index 0000000..dd96bef
--- /dev/null
@@ -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);
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C
new file mode 100644 (file)
index 0000000..f7b46d3
--- /dev/null
@@ -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);
diff --git a/gcc/testsuite/g++.dg/other/pr87398.C b/gcc/testsuite/g++.dg/other/pr87398.C
new file mode 100644 (file)
index 0000000..00a2cd3
--- /dev/null
@@ -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;
+}