Index: include/clang/Analysis/CFG.h =================================================================== --- include/clang/Analysis/CFG.h +++ include/clang/Analysis/CFG.h @@ -667,6 +667,7 @@ bool AddTemporaryDtors; bool AddStaticInitBranches; bool AddCXXNewAllocator; + bool AddCXXDefaultInitExprInCtors; bool alwaysAdd(const Stmt *stmt) const { return alwaysAddMask[stmt->getStmtClass()]; @@ -689,7 +690,8 @@ ,AddImplicitDtors(false) ,AddTemporaryDtors(false) ,AddStaticInitBranches(false) - ,AddCXXNewAllocator(false) {} + ,AddCXXNewAllocator(false) + ,AddCXXDefaultInitExprInCtors(false) {} }; /// \brief Provides a custom implementation of the iterator class to have the Index: lib/Analysis/CFG.cpp =================================================================== --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -770,6 +770,19 @@ // generating destructors for the second time. return Visit(cast(Init)->getSubExpr()); } + CXXDefaultInitExpr *Default; + if (BuildOpts.AddCXXDefaultInitExprInCtors && + (Default = dyn_cast(Init))) { + // In general, appending the expression wrapped by a CXXDefaultInitExpr + // may cause the same Expr to appear more than once in the CFG. Doing it + // here is safe because there's only one initializer per field. + autoCreateBlock(); + appendStmt(Block, Default); + if (Stmt *Child = Default->getExpr()) + if (CFGBlock *R = Visit(Child)) + Block = R; + return Block; + } return Visit(Init); }