diff options
| author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-07-23 20:15:50 +0000 |
|---|---|---|
| committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-07-23 20:15:50 +0000 |
| commit | dccc30a7efe2e20b4263ca50171aaae55ef6b5a2 (patch) | |
| tree | 54c3e03176fc63c1ce3722d4b7661102c34cb7a2 /clang | |
| parent | f0eafc78e08397c1ccb35acdd8105529369dce68 (diff) | |
| download | bcm5719-llvm-dccc30a7efe2e20b4263ca50171aaae55ef6b5a2.tar.gz bcm5719-llvm-dccc30a7efe2e20b4263ca50171aaae55ef6b5a2.zip | |
Sema: Avoid a stack overflow on large CFGs
Large CFGs cause `checkForFunctionCall()` to overflow its stack. Break
the recursion by manually managing the call stack instead.
Patch by Vedant Kumar!
llvm-svn: 243039
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 501b862cefb..59c25d235a6 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -207,27 +207,35 @@ static void checkForFunctionCall(Sema &S, const FunctionDecl *FD, CFGBlock &Block, unsigned ExitID, llvm::SmallVectorImpl<RecursiveState> &States, RecursiveState State) { - unsigned ID = Block.getBlockID(); + SmallVector<std::pair<CFGBlock *, RecursiveState>, 16> Stack; + Stack.emplace_back(&Block, State); - // A block's state can only move to a higher state. - if (States[ID] >= State) - return; + while (!Stack.empty()) { + CFGBlock &CurBlock = *Stack.back().first; + RecursiveState CurState = Stack.back().second; + Stack.pop_back(); - States[ID] = State; + unsigned ID = CurBlock.getBlockID(); - if (State == FoundPathWithNoRecursiveCall) { - // Found a path to the exit node without a recursive call. - if (ExitID == ID) - return; + // A block's state can only move to a higher state. + if (States[ID] >= CurState) + continue; - if (hasRecursiveCallInPath(FD, Block)) - State = FoundPath; - } + States[ID] = CurState; - for (CFGBlock::succ_iterator I = Block.succ_begin(), E = Block.succ_end(); - I != E; ++I) - if (*I) - checkForFunctionCall(S, FD, **I, ExitID, States, State); + if (CurState == FoundPathWithNoRecursiveCall) { + // Found a path to the exit node without a recursive call. + if (ExitID == ID) + continue; + + if (hasRecursiveCallInPath(FD, CurBlock)) + CurState = FoundPath; + } + + for (auto I = CurBlock.succ_begin(), E = CurBlock.succ_end(); I != E; ++I) + if (*I) + Stack.emplace_back(*I, CurState); + } } static void checkRecursiveFunction(Sema &S, const FunctionDecl *FD, |

