[clang] fc6b228 - [Static Analyzer][CFG] Introducing the source array in the CFG of DecompositionDecl

via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 17 09:35:30 PDT 2022


Author: isuckatcs
Date: 2022-06-17T18:34:34+02:00
New Revision: fc6b2281bfd747b3e24d23e2ee8de189f741770f

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

LOG: [Static Analyzer][CFG] Introducing the source array in the CFG of DecompositionDecl

For DecompositionDecl, the array, which is being decomposed was not present in the
CFG, which lead to the liveness analysis falsely detecting it as a dead symbol.

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

Added: 
    

Modified: 
    clang/lib/Analysis/CFG.cpp
    clang/test/Analysis/cfg.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 8379e108fa27b..b16898d3ffa0b 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -609,6 +609,7 @@ class CFGBuilder {
                                           AddStmtChoice asc);
   CFGBlock *VisitUnaryOperator(UnaryOperator *U, AddStmtChoice asc);
   CFGBlock *VisitWhileStmt(WhileStmt *W);
+  CFGBlock *VisitArrayInitLoopExpr(ArrayInitLoopExpr *A, AddStmtChoice asc);
 
   CFGBlock *Visit(Stmt *S, AddStmtChoice asc = AddStmtChoice::NotAlwaysAdd,
                   bool ExternallyDestructed = false);
@@ -2330,6 +2331,9 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc,
 
     case Stmt::WhileStmtClass:
       return VisitWhileStmt(cast<WhileStmt>(S));
+
+    case Stmt::ArrayInitLoopExprClass:
+      return VisitArrayInitLoopExpr(cast<ArrayInitLoopExpr>(S), asc);
   }
 }
 
@@ -3881,6 +3885,27 @@ CFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) {
   return EntryConditionBlock;
 }
 
+CFGBlock *CFGBuilder::VisitArrayInitLoopExpr(ArrayInitLoopExpr *A,
+                                             AddStmtChoice asc) {
+  if (asc.alwaysAdd(*this, A)) {
+    autoCreateBlock();
+    appendStmt(Block, A);
+  }
+
+  CFGBlock *B = Block;
+
+  if (CFGBlock *R = Visit(A->getSubExpr()))
+    B = R;
+
+  auto *OVE = dyn_cast<OpaqueValueExpr>(A->getCommonExpr());
+  assert(OVE && "ArrayInitLoopExpr->getCommonExpr() should be wrapped in an "
+                "OpaqueValueExpr!");
+  if (CFGBlock *R = Visit(OVE->getSourceExpr()))
+    B = R;
+
+  return B;
+}
+
 CFGBlock *CFGBuilder::VisitObjCAtCatchStmt(ObjCAtCatchStmt *CS) {
   // ObjCAtCatchStmt are treated like labels, so they are the first statement
   // in a block.

diff  --git a/clang/test/Analysis/cfg.cpp b/clang/test/Analysis/cfg.cpp
index 333ea565287b2..df4c7b32fb685 100644
--- a/clang/test/Analysis/cfg.cpp
+++ b/clang/test/Analysis/cfg.cpp
@@ -650,6 +650,22 @@ int crash_with_thread_local(char *p, int *q) {
   return 0;
 }
 
+// CHECK-LABEL: void DecompositionDecl()
+// CHECK:       [B1]
+// CHECK-NEXT:    1: int arr[2];
+// CHECK-NEXT:    2: arr
+// CHECK-NEXT:    3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)
+// CHECK-NEXT:    4: *
+// CHECK-NEXT:    5: [B1.3]{{\[\[}}B1.4]]
+// CHECK-NEXT:    6: [B1.5] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:    7: {{\{}}[B1.6]{{(\})}}
+// CHECK-NEXT:    8: auto = {{\{}}arr[*]{{(\})}};
+void DecompositionDecl() {
+  int arr[2];
+
+  auto [a, b] = arr;
+}
+
 // CHECK-LABEL: template<> int *PR18472<int>()
 // CHECK: [B2 (ENTRY)]
 // CHECK-NEXT:   Succs (1): B1


        


More information about the cfe-commits mailing list