On 9/21/24 1:54 PM, Arsen Arsenović wrote:
Okay, these patch should work correctly in all cases, at least all I
could think of. The first patch is unchanged, the second one is simpler
than it was before, I think.
---------- >8 ----------
If such a diagnostic is necessary, it has already been emitted,
otherwise, it is not correct and emitting it here is inactionable by the
user, and bogus.
OK.
PR c++/116502
gcc/cp/ChangeLog:
* coroutines.cc (maybe_promote_temps): Convert temporary
initializers to void without complaining.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/maybe-unused-1.C: New test.
* g++.dg/coroutines/pr116502.C: New test.
---
gcc/cp/coroutines.cc | 12 +++++--
.../g++.dg/coroutines/maybe-unused-1.C | 33 +++++++++++++++++++
gcc/testsuite/g++.dg/coroutines/pr116502.C | 33 +++++++++++++++++++
3 files changed, 75 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/coroutines/maybe-unused-1.C
create mode 100644 gcc/testsuite/g++.dg/coroutines/pr116502.C
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 75e8dbbeab1b..f9129b5f988b 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3344,7 +3344,13 @@ maybe_promote_temps (tree *stmt, void *d)
to run the initializer.
If the initializer is a conditional expression, we need to collect
and declare any promoted variables nested within it. DTORs for such
- variables must be run conditionally too. */
+ variables must be run conditionally too.
+
+ Since here we're synthetically processing code here, we've already
+ emitted any Wunused-result warnings. Below, however, we call
+ finish_expr_stmt, which will convert its operand to void, and could
+ result in such a diagnostic being emitted. To avoid that, convert to
+ void ahead of time. */
if (t->var)
{
tree var = t->var;
@@ -3354,7 +3360,7 @@ maybe_promote_temps (tree *stmt, void *d)
if (TREE_CODE (t->init) == COND_EXPR)
process_conditional (t, vlist);
else
- finish_expr_stmt (t->init);
+ finish_expr_stmt (convert_to_void (t->init, ICV_STATEMENT,
tf_none));
if (tree cleanup = cxx_maybe_build_cleanup (var, tf_warning_or_error))
{
tree cl = build_stmt (sloc, CLEANUP_STMT, expr_list, cleanup,
var);
@@ -3373,7 +3379,7 @@ maybe_promote_temps (tree *stmt, void *d)
if (TREE_CODE (t->init) == COND_EXPR)
process_conditional (t, vlist);
else
- finish_expr_stmt (t->init);
+ finish_expr_stmt (convert_to_void (t->init, ICV_STATEMENT,
tf_none));
if (expr_list)
{
if (TREE_CODE (expr_list) != STATEMENT_LIST)
diff --git a/gcc/testsuite/g++.dg/coroutines/maybe-unused-1.C
b/gcc/testsuite/g++.dg/coroutines/maybe-unused-1.C
new file mode 100644
index 000000000000..68d59d83e8eb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/maybe-unused-1.C
@@ -0,0 +1,33 @@
+// https://gcc.gnu.org/PR116502
+#include <coroutine>
+
+struct SuspendNever {
+ bool await_ready() noexcept;
+ void await_suspend(std::coroutine_handle<>) noexcept;
+ void await_resume() noexcept;
+};
+
+struct Coroutine;
+
+struct PromiseType {
+ Coroutine get_return_object();
+ SuspendNever initial_suspend();
+ SuspendNever final_suspend() noexcept;
+ void return_void();
+ void unhandled_exception();
+};
+
+struct Coroutine {
+ using promise_type = PromiseType;
+};
+
+struct Awaiter {
+ bool await_ready();
+ void await_suspend(std::coroutine_handle<>);
+ [[nodiscard]] int& await_resume();
+};
+
+Coroutine foo()
+{
+ co_await Awaiter {}; // { dg-warning "Wunused-result" }
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr116502.C
b/gcc/testsuite/g++.dg/coroutines/pr116502.C
new file mode 100644
index 000000000000..95cc0bc8a983
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr116502.C
@@ -0,0 +1,33 @@
+// https://gcc.gnu.org/PR116502
+#include <coroutine>
+
+struct SuspendNever {
+ bool await_ready() noexcept;
+ void await_suspend(std::coroutine_handle<>) noexcept;
+ void await_resume() noexcept;
+};
+
+struct Coroutine;
+
+struct PromiseType {
+ Coroutine get_return_object();
+ SuspendNever initial_suspend();
+ SuspendNever final_suspend() noexcept;
+ void return_void();
+ void unhandled_exception();
+};
+
+struct Coroutine {
+ using promise_type = PromiseType;
+};
+
+struct Awaiter {
+ bool await_ready();
+ void await_suspend(std::coroutine_handle<>);
+ [[nodiscard]] int& await_resume();
+};
+
+Coroutine foo()
+{
+ (void)co_await Awaiter {};
+}