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