Author: Nathan Sidwell
Date: 2022-05-26T06:40:43-07:00
New Revision: 6b8c6f15fdd8c147dfb7b0beb6f3d6eb98bf5772

URL: 
https://github.com/llvm/llvm-project/commit/6b8c6f15fdd8c147dfb7b0beb6f3d6eb98bf5772
DIFF: 
https://github.com/llvm/llvm-project/commit/6b8c6f15fdd8c147dfb7b0beb6f3d6eb98bf5772.diff

LOG: [clang][PR55406] CFG for coroutine

CoreturnStmt needs to keep the operand value distinct from its use in
any return_value call, so that instantiation may rebuild the latter.
But it also needs to keep the operand value separate in the case of
calling return_void.  Code generation checks the operand value form to
determine whether it is a distincte entity to the promise call.  This
adds the same logic to CFG generation.

Reviewed By: bruno

Differential Revision: https://reviews.llvm.org/D126399

Added: 
    clang/test/SemaCXX/thread-safety-coro.cpp

Modified: 
    clang/lib/Analysis/CFG.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index fd8d1b196f114..1417b95aad931 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -3137,8 +3137,19 @@ CFGBlock *CFGBuilder::VisitReturnStmt(Stmt *S) {
       return Visit(O, AddStmtChoice::AlwaysAdd, /*ExternallyDestructed=*/true);
     return Block;
   }
-  // co_return
-  return VisitChildren(S);
+
+  CoreturnStmt *CRS = cast<CoreturnStmt>(S);
+  auto *B = Block;
+  if (CFGBlock *R = Visit(CRS->getPromiseCall()))
+    B = R;
+
+  if (Expr *RV = CRS->getOperand())
+    if (RV->getType()->isVoidType() && !isa<InitListExpr>(RV))
+      // A non-initlist void expression.
+      if (CFGBlock *R = Visit(RV))
+        B = R;
+
+  return B;
 }
 
 CFGBlock *CFGBuilder::VisitSEHExceptStmt(SEHExceptStmt *ES) {

diff  --git a/clang/test/SemaCXX/thread-safety-coro.cpp 
b/clang/test/SemaCXX/thread-safety-coro.cpp
new file mode 100644
index 0000000000000..a500ad5435e4a
--- /dev/null
+++ b/clang/test/SemaCXX/thread-safety-coro.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++17 
-fcoroutines-ts %s
+
+// expected-no-diagnostics
+
+namespace std {
+template <typename _Result, typename...>
+struct coroutine_traits {
+  using promise_type = typename _Result::promise_type;
+};
+
+template <typename _Promise = void>
+struct coroutine_handle;
+
+template <>
+struct coroutine_handle<void> {
+  static coroutine_handle from_address(void *__a) noexcept;
+  void resume() const noexcept;
+  void destroy() const noexcept;
+};
+
+template <typename _Promise>
+struct coroutine_handle : coroutine_handle<> {};
+
+struct suspend_always {
+  bool await_ready() const noexcept;
+  void await_suspend(coroutine_handle<>) const noexcept;
+  void await_resume() const noexcept;
+};
+} // namespace std
+
+class Task {
+public:
+  struct promise_type {
+  public:
+    std::suspend_always initial_suspend() noexcept;
+    std::suspend_always final_suspend() noexcept;
+
+    Task get_return_object() noexcept;
+    void unhandled_exception() noexcept;
+    void return_value(int value) noexcept;
+  };
+};
+
+Task Foo() noexcept {
+  // ICE'd
+  co_return({ int frame = 0; 0; });
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to