llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-coroutines

Author: Yuxuan Chen (yuxuanchen1997)

<details>
<summary>Changes</summary>

This PR is proposing a fix for 
https://github.com/llvm/llvm-project/issues/65971.

Previously, given a coroutine like this
```
task foo(int a) {
  co_return;
}
```
Parameter `a` is never used. However, because C++ coroutines move constructs 
the variable to a heap allocated coroutine activation frame, we considered all 
parameters referenced. When diagnosing unused parameters, we cannot distinguish 
if the variable reference was due to coroutine parameter moves. 

Compiler Explorer shows that GCC warns against this case correctly, but clang 
does not: https://godbolt.org/z/Wo7dfqeaf

This patch addresses this issue by preserving the original `ParmVarDecl`'s 
`Referenced` state.

---
Full diff: https://github.com/llvm/llvm-project/pull/70973.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaCoroutine.cpp (+6) 
- (added) clang/test/SemaCXX/warn-unused-parameters-coroutine.cpp (+34) 


``````````diff
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index 38ac406b14adadf..bee80db8d166a68 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -1965,9 +1965,15 @@ bool Sema::buildCoroutineParameterMoves(SourceLocation 
Loc) {
     if (PD->getType()->isDependentType())
       continue;
 
+    // Preserve the referenced state for unused parameter diagnostics.
+    bool DeclReferenced = PD->isReferenced();
+
     ExprResult PDRefExpr =
         BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
                          ExprValueKind::VK_LValue, Loc); // FIXME: scope?
+
+    PD->setReferenced(DeclReferenced);
+
     if (PDRefExpr.isInvalid())
       return false;
 
diff --git a/clang/test/SemaCXX/warn-unused-parameters-coroutine.cpp 
b/clang/test/SemaCXX/warn-unused-parameters-coroutine.cpp
new file mode 100644
index 000000000000000..b4c01550f9f7883
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unused-parameters-coroutine.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-parameter -verify -std=c++20 %s
+
+#include "Inputs/std-coroutine.h"
+
+struct awaitable {
+  bool await_ready() noexcept;
+  void await_resume() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+};
+
+struct task : awaitable {
+  struct promise_type {
+    task get_return_object() noexcept;
+    awaitable initial_suspend() noexcept;
+    awaitable final_suspend() noexcept;
+    void unhandled_exception() noexcept;
+    void return_void() noexcept;
+  };
+};
+
+task foo(int a) { // expected-warning{{unused parameter 'a'}}
+  co_return;
+}
+
+task bar(int a, int b) { // expected-warning{{unused parameter 'b'}}
+  a = a + 1;
+  co_return;
+}
+
+void create_closure() {
+  auto closure = [](int c) -> task { // expected-warning{{unused parameter 
'c'}}
+    co_return;
+  };
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/70973
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to