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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits