diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/constexpr.cc | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/constexpr-dtor15.C | 19 |
2 files changed, 30 insertions, 4 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 3de60cf..d109776 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -7230,16 +7230,23 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, non_constant_p, overflow_p); if (*non_constant_p) break; - /* Adjust the type of the result to the type of the temporary. */ - r = adjust_temp_type (type, r); + /* If the initializer is complex, evaluate it to initialize slot. */ + bool is_complex = target_expr_needs_replace (t); + if (!is_complex) + { + r = unshare_constructor (r); + /* Adjust the type of the result to the type of the temporary. */ + r = adjust_temp_type (type, r); + ctx->global->put_value (slot, r); + } if (TARGET_EXPR_CLEANUP (t) && !CLEANUP_EH_ONLY (t)) ctx->global->cleanups->safe_push (TARGET_EXPR_CLEANUP (t)); - r = unshare_constructor (r); - ctx->global->put_value (slot, r); if (ctx->save_exprs) ctx->save_exprs->safe_push (slot); if (lval) return slot; + if (is_complex) + r = ctx->global->get_value (slot); } break; diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor15.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor15.C new file mode 100644 index 0000000..d34c27e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor15.C @@ -0,0 +1,19 @@ +// PR c++/109357 +// { dg-do compile { target c++20 } } +// { dg-prune-output "used but never defined" } + +struct basic_string { + char _M_local_buf; + basic_string(); + constexpr basic_string(const char *) {} + constexpr ~basic_string(); + constexpr basic_string& operator=(basic_string); +}; +struct S1 { + basic_string x; + basic_string y; +} s1; +struct s2 { + ~s2(); +}; +s2::~s2() { s1 = {"", ""}; } |