c++: noexcept and copy elision [PR109030]
authorMarek Polacek <polacek@redhat.com>
Mon, 6 Mar 2023 23:06:39 +0000 (18:06 -0500)
committerMarek Polacek <polacek@redhat.com>
Tue, 7 Mar 2023 15:13:53 +0000 (10:13 -0500)
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
gcc/testsuite/g++.dg/cpp0x/noexcept77.C [new file with mode: 0644]

index 3079561..8683c00 100644 (file)
@@ -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 (file)
index 0000000..16db8eb
--- /dev/null
@@ -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})) { }