================
@@ -453,70 +455,35 @@ bool DeadCodeScan::isDeadCodeRoot(const clang::CFGBlock 
*Block) {
   return isDeadRoot;
 }
 
-// Check if the given `DeadStmt` is a coroutine statement and is a substmt of
-// the coroutine statement. `Block` is the CFGBlock containing the `DeadStmt`.
-static bool isInCoroutineStmt(const Stmt *DeadStmt, const CFGBlock *Block) {
-  // The coroutine statement, co_return, co_await, or co_yield.
-  const Stmt *CoroStmt = nullptr;
-  // Find the first coroutine statement after the DeadStmt in the block.
-  bool AfterDeadStmt = false;
-  for (CFGBlock::const_iterator I = Block->begin(), E = Block->end(); I != E;
-       ++I)
-    if (std::optional<CFGStmt> CS = I->getAs<CFGStmt>()) {
-      const Stmt *S = CS->getStmt();
-      if (S == DeadStmt)
-        AfterDeadStmt = true;
-      if (AfterDeadStmt &&
-          // For simplicity, we only check simple coroutine statements.
-          (llvm::isa<CoreturnStmt>(S) || llvm::isa<CoroutineSuspendExpr>(S))) {
-        CoroStmt = S;
-        break;
-      }
-    }
-  if (!CoroStmt)
-    return false;
-  struct Checker : DynamicRecursiveASTVisitor {
-    const Stmt *DeadStmt;
-    bool CoroutineSubStmt = false;
-    Checker(const Stmt *S) : DeadStmt(S) {
-      // Statements captured in the CFG can be implicit.
-      ShouldVisitImplicitCode = true;
-    }
-
-    bool VisitStmt(Stmt *S) override {
-      if (S == DeadStmt)
-        CoroutineSubStmt = true;
-      return true;
-    }
-  };
-  Checker checker(DeadStmt);
-  checker.TraverseStmt(const_cast<Stmt *>(CoroStmt));
-  return checker.CoroutineSubStmt;
-}
-
-static bool isValidDeadStmt(const Stmt *S, const clang::CFGBlock *Block) {
+static bool isValidDeadStmt(ParentMap &PM, const Stmt *S, const 
clang::CFGBlock *Block) {
   if (S->getBeginLoc().isInvalid())
     return false;
   if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(S))
     return BO->getOpcode() != BO_Comma;
   // Coroutine statements are never considered dead statements, because 
removing
   // them may change the function semantic if it is the only coroutine 
statement
   // of the coroutine.
-  return !isInCoroutineStmt(S, Block);
+  return !PM.getInnerMostAncestor<CoreturnStmt, CoroutineSuspendExpr>(S);
 }
 
 const Stmt *DeadCodeScan::findDeadCode(const clang::CFGBlock *Block) {
+  auto &PM = AC.getParentMap();
+
   for (CFGBlock::const_iterator I = Block->begin(), E = Block->end(); I!=E; 
++I)
     if (std::optional<CFGStmt> CS = I->getAs<CFGStmt>()) {
       const Stmt *S = CS->getStmt();
-      if (isValidDeadStmt(S, Block))
+      auto *RewrittenParent =
+          PM.getOuterMostAncestor<CXXDefaultArgExpr, CXXDefaultInitExpr>(S);
----------------
yronglin wrote:

I try to fix Nico's example(https://github.com/llvm/llvm-project/issues/128195) 
about the wrong unrachable code location. The root cause of this issue is that 
this PR introduce "rewritten" expressions in `CFGBlock`. When we are finding 
the real dead code, we should try to ignore the "rewritten" sub-expression 
nodes in `CXXDefaultInitExpr`/`CXXDefaultArgExpr`, but I'm not sure this option 
is make sense. What do you think?

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

Reply via email to