Index: clang/include/clang/Analysis/CFG.h =================================================================== --- clang/include/clang/Analysis/CFG.h +++ clang/include/clang/Analysis/CFG.h @@ -1248,6 +1248,7 @@ bool AddStaticInitBranches = false; bool AddCXXNewAllocator = false; bool AddCXXDefaultInitExprInCtors = false; + bool AddCXXDefaultInitExprInAggregates = false; bool AddRichCXXConstructors = false; bool MarkElidedCXXConstructors = false; bool AddVirtualBaseBranches = false; Index: clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def =================================================================== --- clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -112,6 +112,11 @@ bool, ShouldIncludeScopesInCFG, "cfg-scopes", "Whether or not scope information should be included in the CFG.", false) +ANALYZER_OPTION(bool, ShouldIncludeDefaultInitForAggregates, "cfg-aggr-definit", + "Whether or not inline CXXDefaultInitializers for aggregat " + "initialization in the CFG.", + false) + ANALYZER_OPTION( bool, MayInlineTemplateFunctions, "c++-template-inlining", "Whether or not templated functions may be considered for inlining.", true) Index: clang/lib/Analysis/CFG.cpp =================================================================== --- clang/lib/Analysis/CFG.cpp +++ clang/lib/Analysis/CFG.cpp @@ -542,6 +542,7 @@ private: // Visitors to walk an AST and construct the CFG. + CFGBlock *VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc); CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc); CFGBlock *VisitBinaryOperator(BinaryOperator *B, AddStmtChoice asc); CFGBlock *VisitBreakStmt(BreakStmt *B); @@ -2140,6 +2141,9 @@ return Block; return VisitStmt(S, asc); + case Stmt::InitListExprClass: + return VisitInitListExpr(cast(S), asc); + case Stmt::AddrLabelExprClass: return VisitAddrLabelExpr(cast(S), asc); @@ -2355,6 +2359,29 @@ return B; } +CFGBlock *CFGBuilder::VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc) { + if (asc.alwaysAdd(*this, ILE)) { + autoCreateBlock(); + appendStmt(Block, ILE); + } + CFGBlock *B = Block; + + reverse_children RChildren(ILE); + for (reverse_children::iterator I = RChildren.begin(), E = RChildren.end(); + I != E; ++I) { + if (Stmt *Child = *I) + if (CFGBlock *R = Visit(Child)) + B = R; + if (BuildOpts.AddCXXDefaultInitExprInAggregates) { + if (auto *DIE = dyn_cast_or_null(*I)) + if (Stmt *Child = DIE->getExpr()) + if (CFGBlock *R = Visit(Child)) + B = R; + } + } + return B; +} + CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc) { AddressTakenLabels.insert(A->getLabel()); Index: clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp +++ clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp @@ -44,6 +44,8 @@ options(Options) { AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd(); AnaCtxMgr.getCFGBuildOptions().OmitImplicitValueInitializers = true; + AnaCtxMgr.getCFGBuildOptions().AddCXXDefaultInitExprInAggregates = + Options.ShouldIncludeDefaultInitForAggregates; } AnalysisManager::~AnalysisManager() { Index: clang/test/Analysis/analyzer-config.c =================================================================== --- clang/test/Analysis/analyzer-config.c +++ clang/test/Analysis/analyzer-config.c @@ -18,6 +18,7 @@ // CHECK-NEXT: c++-stdlib-inlining = true // CHECK-NEXT: c++-temp-dtor-inlining = true // CHECK-NEXT: c++-template-inlining = true +// CHECK-NEXT: cfg-aggr-definit = false // CHECK-NEXT: cfg-conditional-static-initializers = true // CHECK-NEXT: cfg-implicit-dtors = true // CHECK-NEXT: cfg-lifetime = false @@ -98,4 +99,4 @@ // CHECK-NEXT: unroll-loops = false // CHECK-NEXT: widen-loops = false // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 95 +// CHECK-NEXT: num-entries = 96