diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/AnalysisDeclContext.cpp | 17 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 16 |
2 files changed, 30 insertions, 3 deletions
diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp index bcaad9b0db..20cc3d55f3 100644 --- a/lib/Analysis/AnalysisDeclContext.cpp +++ b/lib/Analysis/AnalysisDeclContext.cpp @@ -86,11 +86,13 @@ static BodyFarm &getBodyFarm(ASTContext &C) { return *BF; } -Stmt *AnalysisDeclContext::getBody() const { +Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const { if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { Stmt *Body = FD->getBody(); - if (!Body && Manager && Manager->synthesizeBodies()) + if (!Body && Manager && Manager->synthesizeBodies()) { + IsAutosynthesized = true; return getBodyFarm(getASTContext()).getBody(FD); + } return Body; } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) @@ -104,6 +106,17 @@ Stmt *AnalysisDeclContext::getBody() const { llvm_unreachable("unknown code decl"); } +Stmt *AnalysisDeclContext::getBody() const { + bool Tmp; + return getBody(Tmp); +} + +bool AnalysisDeclContext::isBodyAutosynthesized() const { + bool Tmp; + getBody(Tmp); + return Tmp; +} + const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const { if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) return MD->getSelfDecl(); diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 2c1f6c1d8f..1d006b09cc 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -733,13 +733,27 @@ void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr, Bldr.generateNode(Call.getProgramPoint(), State, Pred); } +static bool isEssentialToInline(const CallEvent &Call) { + const Decl *D = Call.getDecl(); + if (D) { + AnalysisDeclContext *AD = + Call.getLocationContext()->getAnalysisDeclContext()-> + getManager()->getContext(D); + + // The auto-synthesized bodies are essential to inline as they are + // usually small and commonly used. + return AD->isBodyAutosynthesized(); + } + return false; +} + void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred, const CallEvent &CallTemplate) { // Make sure we have the most recent state attached to the call. ProgramStateRef State = Pred->getState(); CallEventRef<> Call = CallTemplate.cloneWithState(State); - if (HowToInline == Inline_None) { + if (HowToInline == Inline_None && !isEssentialToInline(CallTemplate)) { conservativeEvalCall(*Call, Bldr, Pred, State); return; } |