diff options
author | Jason Merrill <jason@redhat.com> | 2020-01-08 15:31:20 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2020-01-08 15:31:20 -0500 |
commit | 10d2f801f472931137deae1714d5b690c1862037 (patch) | |
tree | f13bc24987acc7188124e8414df9cc31ed103b00 /gcc | |
parent | cd3ca6cb1129b1e80b5b048a59aa3a0c387c2413 (diff) | |
download | gcc-10d2f801f472931137deae1714d5b690c1862037.zip gcc-10d2f801f472931137deae1714d5b690c1862037.tar.gz gcc-10d2f801f472931137deae1714d5b690c1862037.tar.bz2 |
PR c++/91369 - constexpr destructor and member initializer.
Previously it didn't matter whether we looked through a TARGET_EXPR in
constexpr evaluation, but now that we have constexpr destructors it does.
On IRC I mentioned the idea of clearing TARGET_EXPR_CLEANUP in
digest_nsdmi_init, but since this initialization is expressed by an
INIT_EXPR, it's better to handle all INIT_EXPR, not just those for a member
initializer.
* constexpr.c (cxx_eval_store_expression): Look through TARGET_EXPR
when not preevaluating.
From-SVN: r280018
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/constexpr-new10.C | 19 |
3 files changed, 31 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c650fde..7aacbe2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2020-01-08 Jason Merrill <jason@redhat.com> + PR c++/91369 - constexpr destructor and member initializer. + * constexpr.c (cxx_eval_store_expression): Look through TARGET_EXPR + when not preevaluating. + +2020-01-08 Jason Merrill <jason@redhat.com> + * constexpr.c (cxx_eval_call_expression): Remove DECL_BY_REFERENCE support. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 806d3ab..5fe6d02 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4577,6 +4577,12 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, } new_ctx.ctor = *valp; new_ctx.object = target; + /* Avoid temporary materialization when initializing from a TARGET_EXPR. + We don't need to mess with AGGR_EXPR_SLOT/VEC_INIT_EXPR_SLOT because + expansion of those trees uses ctx instead. */ + if (TREE_CODE (init) == TARGET_EXPR) + if (tree tinit = TARGET_EXPR_INITIAL (init)) + init = tinit; init = cxx_eval_constant_expression (&new_ctx, init, false, non_constant_p, overflow_p); if (ctors->is_empty()) diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new10.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new10.C new file mode 100644 index 0000000..500a324 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new10.C @@ -0,0 +1,19 @@ +// PR c++/91369 +// { dg-do compile { target c++2a } } + +struct S { + constexpr S (int* i) : s{i} {} + constexpr ~S () { delete s; } + int *s; +}; + +struct T { S t = { new int }; }; + +constexpr auto +foo () +{ + T b; + return true; +} + +static_assert (foo ()); |