diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-08-15 00:52:00 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-08-15 00:52:00 +0000 |
commit | b763ede873c23c8651bd18eba0c62e929b496ba5 (patch) | |
tree | c624cfd4f66e1d4615263341cccbaadaddf082ee | |
parent | 0ad36baedc516005cb6ea97d96327517ebfe5138 (diff) |
[analyzer] Don't inline dynamic-dispatch methods unless -analyzer-ipa=dynamic.
Previously we were checking -analyzer-ipa=dynamic-bifurcate only, and
unconditionally inlining everything else that had an available definition,
even under -analyzer-ipa=inlining (but not under -analyzer-ipa=none).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161916 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 17 | ||||
-rw-r--r-- | test/Analysis/inlining/dyn-dispatch-bifurcate.cpp | 17 |
2 files changed, 29 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 8ee6723057..5b93dfdb83 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -555,12 +555,18 @@ void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred, RuntimeDefinition RD = Call->getRuntimeDefinition(); const Decl *D = RD.getDecl(); if (D) { - // Explore with and without inlining the call. - if (RD.mayHaveOtherDefinitions() && - getAnalysisManager().IPAMode == DynamicDispatchBifurcate) { - BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred); - return; + if (RD.mayHaveOtherDefinitions()) { + // Explore with and without inlining the call. + if (getAnalysisManager().IPAMode == DynamicDispatchBifurcate) { + BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred); + return; + } + + // Don't inline if we're not in any dynamic dispatch mode. + if (getAnalysisManager().IPAMode != DynamicDispatch) + return; } + // We are not bifurcating and we do have a Decl, so just inline. if (inlineCall(*Call, D, Bldr, Pred, State)) return; @@ -575,6 +581,7 @@ void ExprEngine::BifurcateCall(const MemRegion *BifurReg, const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, ExplodedNode *Pred) { assert(BifurReg); + BifurReg = BifurReg->StripCasts(); // Check if we've performed the split already - note, we only want // to split the path once per memory region. diff --git a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp new file mode 100644 index 0000000000..fa473aebce --- /dev/null +++ b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s + +void clang_analyzer_eval(bool); + +class A { +public: + virtual int get() { return 0; } +}; + +void testBifurcation(A *a) { + clang_analyzer_eval(a->get() == 0); // expected-warning{{TRUE}} expected-warning{{UNKNOWN}} +} + +void testKnown() { + A a; + clang_analyzer_eval(a.get() == 0); // expected-warning{{TRUE}} +} |