aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp17
-rw-r--r--test/Analysis/inlining/dyn-dispatch-bifurcate.cpp17
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}}
+}