diff options
author | Jason Merrill <jason@redhat.com> | 2017-09-18 14:34:10 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-09-18 14:34:10 -0400 |
commit | 54d61eb8e89d857e935de204cf5847ab40514267 (patch) | |
tree | 55a3b5cd08c03e846343c0c641597f8c6ffcd529 | |
parent | ef2dd804cd3547e172ea327d5fb6aff3fd64961a (diff) | |
download | gcc-54d61eb8e89d857e935de204cf5847ab40514267.zip gcc-54d61eb8e89d857e935de204cf5847ab40514267.tar.gz gcc-54d61eb8e89d857e935de204cf5847ab40514267.tar.bz2 |
PR c++/80294 - ICE with constexpr and inheritance.
* constexpr.c (reduced_constant_expression_p):
A null constructor element is non-constant.
(cxx_eval_indirect_ref): Don't VERIFY_CONSTANT before
returning an empty base.
From-SVN: r252940
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-empty3.C | 14 |
3 files changed, 28 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7cfae4e..fedfea7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2017-09-18 Jason Merrill <jason@redhat.com> + PR c++/80294 - ICE with constexpr and inheritance. + * constexpr.c (reduced_constant_expression_p): + A null constructor element is non-constant. + (cxx_eval_indirect_ref): Don't VERIFY_CONSTANT before + returning an empty base. + PR c++/79607 - ICE with T{} initializer * decl.c (type_dependent_init_p): Check the type of a CONSTRUCTOR. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 3f37cd5..4f23f75 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1504,8 +1504,13 @@ reduced_constant_expression_p (tree t) /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */ tree elt; unsigned HOST_WIDE_INT idx; FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, elt) - if (!reduced_constant_expression_p (elt)) - return false; + { + if (!elt) + /* We're in the middle of initializing this element. */ + return false; + if (!reduced_constant_expression_p (elt)) + return false; + } return true; default: @@ -2693,12 +2698,10 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, } } - /* If we're pulling out the value of an empty base, make sure - that the whole object is constant and then return an empty + /* If we're pulling out the value of an empty base, just return an empty CONSTRUCTOR. */ if (empty_base && !lval) { - VERIFY_CONSTANT (r); r = build_constructor (TREE_TYPE (t), NULL); TREE_CONSTANT (r) = true; } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-empty3.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-empty3.C new file mode 100644 index 0000000..37e4a53 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-empty3.C @@ -0,0 +1,14 @@ +// PR c++/80294 +// { dg-do compile { target c++14 } } +// { dg-final { scan-assembler-not "static_init" } } + +struct A { + constexpr int f() { A a = *this; return 42; } +}; +struct B: A +{ + int i; + constexpr B(): i(f()) {} +}; + +B b; |