From: Duncan P. N. Exon Smith Date: Thu, 23 Jul 2015 20:15:50 +0000 (+0000) Subject: Sema: Avoid a stack overflow on large CFGs X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a957e58325c0577eb40ecff009d40c18c39eea1f;p=clang 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! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@243039 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 501b862cef..59c25d235a 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -207,27 +207,35 @@ static void checkForFunctionCall(Sema &S, const FunctionDecl *FD, CFGBlock &Block, unsigned ExitID, llvm::SmallVectorImpl &States, RecursiveState State) { - unsigned ID = Block.getBlockID(); + SmallVector, 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,