diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -609,6 +609,7 @@ 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 @@ case Stmt::WhileStmtClass: return VisitWhileStmt(cast(S)); + + case Stmt::ArrayInitLoopExprClass: + return VisitArrayInitLoopExpr(cast(S), asc); } } @@ -3881,6 +3885,27 @@ 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(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 --- a/clang/test/Analysis/cfg.cpp +++ b/clang/test/Analysis/cfg.cpp @@ -650,6 +650,22 @@ 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() // CHECK: [B2 (ENTRY)] // CHECK-NEXT: Succs (1): B1