diff options
Diffstat (limited to 'lib/Analysis/CFG.cpp')
-rw-r--r-- | lib/Analysis/CFG.cpp | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index ed2239f88ae5..d7a9bdb3d82c 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -1,4 +1,4 @@ - //===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===// +//===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -825,7 +825,7 @@ private: // * Variable x is equal to the largest literal. // * Variable x is greater than largest literal. bool AlwaysTrue = true, AlwaysFalse = true; - for (llvm::APSInt Value : Values) { + for (const llvm::APSInt &Value : Values) { TryResult Res1, Res2; Res1 = analyzeLogicOperatorCondition(BO1, Value, L1); Res2 = analyzeLogicOperatorCondition(BO2, Value, L2); @@ -1945,7 +1945,8 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { addLocalScopeForStmt(C); } if (!C->body_empty() && !isa<ReturnStmt>(*C->body_rbegin())) { - // If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt + // If the body ends with a ReturnStmt, the dtors will be added in + // VisitReturnStmt. addAutomaticObjDtors(ScopePos, scopeBeginPos, C); } @@ -2168,6 +2169,13 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) { // won't be restored when traversing AST. SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); + // Create local scope for C++17 if init-stmt if one exists. + if (Stmt *Init = I->getInit()) { + LocalScope::const_iterator BeginScopePos = ScopePos; + addLocalScopeForStmt(Init); + addAutomaticObjDtors(ScopePos, BeginScopePos, I); + } + // Create local scope for possible condition variable. // Store scope position. Add implicit destructor. if (VarDecl *VD = I->getConditionVariable()) { @@ -2268,13 +2276,19 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) { // blocks will be pointed to be "Block". CFGBlock *LastBlock = addStmt(I->getCond()); - // Finally, if the IfStmt contains a condition variable, add it and its + // If the IfStmt contains a condition variable, add it and its // initializer to the CFG. if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) { autoCreateBlock(); LastBlock = addStmt(const_cast<DeclStmt *>(DS)); } + // Finally, if the IfStmt contains a C++17 init-stmt, add it to the CFG. + if (Stmt *Init = I->getInit()) { + autoCreateBlock(); + LastBlock = addStmt(Init); + } + return LastBlock; } @@ -3059,6 +3073,13 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { // won't be restored when traversing AST. SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); + // Create local scope for C++17 switch init-stmt if one exists. + if (Stmt *Init = Terminator->getInit()) { + LocalScope::const_iterator BeginScopePos = ScopePos; + addLocalScopeForStmt(Init); + addAutomaticObjDtors(ScopePos, BeginScopePos, Terminator); + } + // Create local scope for possible condition variable. // Store scope position. Add implicit destructor. if (VarDecl *VD = Terminator->getConditionVariable()) { @@ -3138,7 +3159,7 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { Block = SwitchTerminatedBlock; CFGBlock *LastBlock = addStmt(Terminator->getCond()); - // Finally, if the SwitchStmt contains a condition variable, add both the + // If the SwitchStmt contains a condition variable, add both the // SwitchStmt and the condition variable initialization to the CFG. if (VarDecl *VD = Terminator->getConditionVariable()) { if (Expr *Init = VD->getInit()) { @@ -3148,6 +3169,12 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { } } + // Finally, if the SwitchStmt contains a C++17 init-stmt, add it to the CFG. + if (Stmt *Init = Terminator->getInit()) { + autoCreateBlock(); + LastBlock = addStmt(Init); + } + return LastBlock; } @@ -3397,8 +3424,10 @@ CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) { // Create local scopes and destructors for range, begin and end variables. if (Stmt *Range = S->getRangeStmt()) addLocalScopeForStmt(Range); - if (Stmt *BeginEnd = S->getBeginEndStmt()) - addLocalScopeForStmt(BeginEnd); + if (Stmt *Begin = S->getBeginStmt()) + addLocalScopeForStmt(Begin); + if (Stmt *End = S->getEndStmt()) + addLocalScopeForStmt(End); addAutomaticObjDtors(ScopePos, save_scope_pos.get(), S); LocalScope::const_iterator ContinueScopePos = ScopePos; @@ -3455,6 +3484,8 @@ CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) { // continue statements. Block = nullptr; Succ = addStmt(S->getInc()); + if (badCFG) + return nullptr; ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos); // The starting block for the loop increment is the block that should @@ -3489,7 +3520,8 @@ CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) { // Add the initialization statements. Block = createBlock(); - addStmt(S->getBeginEndStmt()); + addStmt(S->getBeginStmt()); + addStmt(S->getEndStmt()); return addStmt(S->getRangeStmt()); } @@ -4514,7 +4546,7 @@ void CFGBlock::dump(const CFG* cfg, const LangOptions &LO, print(llvm::errs(), cfg, LO, ShowColors); } -void CFGBlock::dump() const { +LLVM_DUMP_METHOD void CFGBlock::dump() const { dump(getParent(), LangOptions(), false); } |