Currently, GCC misses a diagnostic when discarding a CO_AWAIT_EXPR
resulting in a reference type, because such an expression is wrapped in
an INDIRECT_REF in finish_co_await_expr.  Similar handling is necessary
for CALL_EXPRs, so extend it to also handle CO_AWAIT_EXPR.

gcc/cp/ChangeLog:

        * cvt.cc (convert_co_await_to_void): New function.  Extracted
        from the convert_to_void CO_AWAIT_EXPR case for reuse in the
        INDIRECT_REF case.
        (convert_to_void) <case INDIRECT_REF>: If met with a
        CO_AWAIT_EXPR, call convert_co_await_to_void on it.
        <case CO_AWAIT_EXPR>: Use new helper.
---
 gcc/cp/cvt.cc | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
index b6b35ef9cacf..ce26cb8ef30f 100644
--- a/gcc/cp/cvt.cc
+++ b/gcc/cp/cvt.cc
@@ -1139,6 +1139,20 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
     }
 }
 
+/* Converts the await-resume of a given co_await expr to void.  This is useful
+   because the await-resume expression is the result of the entire
+   co_await, so discarding the result of a co_await is the same as discarding
+   the result of its await-resume expr.  */
+
+void
+convert_co_await_to_void (tree expr, impl_conv_void implicit,
+                         tsubst_flags_t complain)
+{
+  auto awr = co_await_get_resume_call (expr);
+  if (awr)
+    convert_to_void (awr, implicit, complain);
+}
+
 /* When an expression is used in a void context, its value is discarded and
    no lvalue-rvalue and similar conversions happen [expr.static.cast/4,
    stmt.expr/1, expr.comma/1].  This permits dereferencing an incomplete type
@@ -1421,6 +1435,8 @@ convert_to_void (tree expr, impl_conv_void implicit, 
tsubst_flags_t complain)
            if (TREE_CODE (expr) == CALL_EXPR
                && (complain & tf_warning))
              maybe_warn_nodiscard (expr, implicit);
+           else if (TREE_CODE (expr) == CO_AWAIT_EXPR)
+             convert_co_await_to_void (expr, implicit, complain);
           }
 
        break;
@@ -1503,12 +1519,8 @@ convert_to_void (tree expr, impl_conv_void implicit, 
tsubst_flags_t complain)
       break;
 
     case CO_AWAIT_EXPR:
-      {
-       auto awr = co_await_get_resume_call (expr);
-       if (awr)
-         awr = convert_to_void (awr, implicit, complain);
-       break;
-      }
+      convert_co_await_to_void (expr, implicit, complain);
+      break;
 
     default:;
     }
-- 
2.46.0

Reply via email to