From: Jakub Jelinek Date: Tue, 25 Sep 2018 16:40:57 +0000 (+0200) Subject: re PR c++/87398 (g++ ICE on valid code: tree check: expected record_type or union_typ... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=69deaf149a531fe55c058b87609f9f1c56ab6fc6;p=gcc.git re PR c++/87398 (g++ ICE on valid code: tree check: expected record_type or union_type or qual_union_type, have array_type in cxx_eval_constant_expression, at cp/constexpr.c:4820) PR c++/87398 * constexpr.c (cxx_eval_constant_expression) : 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9ce845d20ac..672626c27d9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-09-25 Jakub Jelinek + + PR c++/87398 + * constexpr.c (cxx_eval_constant_expression) : Only + look through COMPONENT_REFs with DECL_FIELD_IS_BASE FIELD_DECLs. + 2018-09-25 Martin Liska * name-lookup.c (namespace_scope_ht_size): Remove diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 08d00e859d8..403edda8c47 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 24bf238e0f6..68f1c3d9a2b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2018-09-25 Jakub Jelinek + + 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 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 index 00000000000..dd96bef1810 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual10.C @@ -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 index 00000000000..f7b46d3098f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual11.C @@ -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 index 00000000000..00a2cd3f1c7 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/pr87398.C @@ -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; +}