From e4692319fd5fc7d740436e8bb338f44cb8df6c58 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Mon, 6 Mar 2023 18:06:39 -0500 Subject: [PATCH] c++: noexcept and copy elision [PR109030] When processing a noexcept, constructors aren't elided: build_over_call has /* It's unsafe to elide the constructor when handling a noexcept-expression, it may evaluate to the wrong value (c++/53025). */ && (force_elide || cp_noexcept_operand == 0)) so the assert I added recently needs to be relaxed a little bit. PR c++/109030 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Relax assert. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept77.C: New test. --- gcc/cp/constexpr.cc | 6 +++++- gcc/testsuite/g++.dg/cpp0x/noexcept77.C | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept77.C diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 3079561..8683c00 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -2869,7 +2869,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, /* We used to shortcut trivial constructor/op= here, but nowadays we can only get a trivial function here with -fno-elide-constructors. */ - gcc_checking_assert (!trivial_fn_p (fun) || !flag_elide_constructors); + gcc_checking_assert (!trivial_fn_p (fun) + || !flag_elide_constructors + /* We don't elide constructors when processing + a noexcept-expression. */ + || cp_noexcept_operand); bool non_constant_args = false; new_call.bindings diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept77.C b/gcc/testsuite/g++.dg/cpp0x/noexcept77.C new file mode 100644 index 0000000..16db8eb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept77.C @@ -0,0 +1,9 @@ +// PR c++/109030 +// { dg-do compile { target c++11 } } + +struct foo { }; + +struct __as_receiver { + foo empty_env; +}; +void sched(foo __fun) noexcept(noexcept(__as_receiver{__fun})) { } -- 2.7.4