Hm, maybe-unused-1.C should be moved into the previous patch.  Could do
before pushing.
---------- >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.

        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 166978ab464b..780dc506825b 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3147,7 +3147,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;
@@ -3157,7 +3163,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);
@@ -3176,7 +3182,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 {};
+}
-- 
2.46.0

Reply via email to