From: Anna Zaks Date: Mon, 10 Sep 2012 23:35:11 +0000 (+0000) Subject: [analyzer] Do not count calls to small functions when computing stack X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ea9b89ff6dc50d5404eb56cad5e5870bce49ef2;p=clang [analyzer] Do not count calls to small functions when computing stack depth. We only want to count how many substantial functions we inlined. This is an improvement to r163558. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163571 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index ffc1698891..690ead02a0 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -496,6 +496,10 @@ private: ProgramStateRef St, SVal location, const ProgramPointTag *tag, bool isLoad); + /// Count the stack depth and determine if the call is recursive. + void examineStackFrames(const Decl *D, const LocationContext *LCtx, + bool &IsRecursive, unsigned &StackDepth); + bool shouldInlineDecl(const Decl *D, ExplodedNode *Pred); bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State); diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 54c66d37ba..eb5395e93c 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -247,18 +247,33 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { } } -static void examineStackFrames(const Decl *D, const LocationContext *LCtx, +void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx, bool &IsRecursive, unsigned &StackDepth) { IsRecursive = false; StackDepth = 0; + while (LCtx) { if (const StackFrameContext *SFC = dyn_cast(LCtx)) { - ++StackDepth; - if (SFC->getDecl() == D) + const Decl *DI = SFC->getDecl(); + + // Mark recursive (and mutually recursive) functions and always count + // them when measuring the stack depth. + if (DI == D) { IsRecursive = true; + ++StackDepth; + LCtx = LCtx->getParent(); + continue; + } + + // Do not count the small functions when determining the stack depth. + AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI); + const CFG *CalleeCFG = CalleeADC->getCFG(); + if (CalleeCFG->getNumBlockIDs() > AMgr.options.getAlwaysInlineSize()) + ++StackDepth; } LCtx = LCtx->getParent(); } + } static bool IsInStdNamespace(const FunctionDecl *FD) { diff --git a/test/Analysis/inlining/test-always-inline-size-option.c b/test/Analysis/inlining/test-always-inline-size-option.c index ef604c2128..6b3c13d2b6 100644 --- a/test/Analysis/inlining/test-always-inline-size-option.c +++ b/test/Analysis/inlining/test-always-inline-size-option.c @@ -2,6 +2,11 @@ void clang_analyzer_eval(int); int nested5() { + if (5 < 3) + return 0; + else + if (3 == 3) + return 0; return 0; } int nested4() { @@ -28,3 +33,16 @@ int recursive() { int callRecursive() { return recursive(); } + +int mutuallyRecursive1(); + +int mutuallyRecursive2() { + return mutuallyRecursive1(); +} + +int mutuallyRecursive1() { + return mutuallyRecursive2(); +} +int callMutuallyRecursive() { + return mutuallyRecursive1(); +}