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;
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.
--- /dev/null
+// 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}}
+}