Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===================================================================
--- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -1788,12 +1788,6 @@
ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
BugReporterContext &BRC, BugReport &BR) {
ProgramPoint progPoint = N->getLocation();
- ProgramStateRef CurrentState = N->getState();
- ProgramStateRef PreviousState = N->getFirstPred()->getState();
-
- // If the constraint information does not changed there is no assumption.
- if (BRC.getStateManager().haveEqualConstraints(CurrentState, PreviousState))
- return nullptr;
// If an assumption was made on a branch, it should be caught
// here by looking at the state transition.
@@ -1881,6 +1875,18 @@
ConditionBRVisitor::VisitTrueTest(const Expr *Cond, bool tookTrue,
BugReporterContext &BRC, BugReport &R,
const ExplodedNode *N) {
+ ProgramStateRef CurrentState = N->getState();
+ ProgramStateRef PreviousState = N->getFirstPred()->getState();
+ const LocationContext *LCtx = N->getLocationContext();
+
+ // If the constraint information is changed between the current and the
+ // previous program state we assuming the newly seen constraint information.
+ // If we cannot evaluate the condition (and the constraints are the same)
+ // the analyzer has no information about the value and just assuming it.
+ if (BRC.getStateManager().haveEqualConstraints(CurrentState, PreviousState) &&
+ CurrentState->getSVal(Cond, LCtx).isValid())
+ return nullptr;
+
// These will be modified in code below, but we need to preserve the original
// values in case we want to throw the generic message.
const Expr *CondTmp = Cond;
@@ -1916,7 +1922,6 @@
// Condition too complex to explain? Just say something so that the user
// knew we've made some path decision at this point.
- const LocationContext *LCtx = N->getLocationContext();
PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
if (!Loc.isValid() || !Loc.asLocation().isValid())
return nullptr;
Index: test/Analysis/Inputs/expected-plists/edges-new.mm.plist
===================================================================
--- test/Analysis/Inputs/expected-plists/edges-new.mm.plist
+++ test/Analysis/Inputs/expected-plists/edges-new.mm.plist
@@ -7305,6 +7305,69 @@
file0
+ end
+
+
+ line263
+ col7
+ file0
+
+
+ line263
+ col7
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line263
+ col7
+ file0
+
+ ranges
+
+
+
+ line263
+ col7
+ file0
+
+
+ line263
+ col14
+ file0
+
+
+
+ depth0
+ extended_message
+ Assuming the condition is false
+ message
+ Assuming the condition is false
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line263
+ col7
+ file0
+
+
+ line263
+ col7
+ file0
+
+
end
@@ -7626,6 +7689,69 @@
file0
+ end
+
+
+ line263
+ col7
+ file0
+
+
+ line263
+ col7
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line263
+ col7
+ file0
+
+ ranges
+
+
+
+ line263
+ col7
+ file0
+
+
+ line263
+ col14
+ file0
+
+
+
+ depth0
+ extended_message
+ Assuming the condition is false
+ message
+ Assuming the condition is false
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line263
+ col7
+ file0
+
+
+ line263
+ col7
+ file0
+
+
end
@@ -8118,6 +8244,69 @@
file0
+ end
+
+
+ line276
+ col7
+ file0
+
+
+ line276
+ col7
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line276
+ col7
+ file0
+
+ ranges
+
+
+
+ line276
+ col7
+ file0
+
+
+ line276
+ col21
+ file0
+
+
+
+ depth0
+ extended_message
+ Assuming the condition is false
+ message
+ Assuming the condition is false
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line276
+ col7
+ file0
+
+
+ line276
+ col7
+ file0
+
+
end
@@ -8186,6 +8375,69 @@
file0
+ end
+
+
+ line276
+ col30
+ file0
+
+
+ line276
+ col30
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line276
+ col30
+ file0
+
+ ranges
+
+
+
+ line276
+ col30
+ file0
+
+
+ line276
+ col37
+ file0
+
+
+
+ depth0
+ extended_message
+ Assuming the condition is true
+ message
+ Assuming the condition is true
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line276
+ col30
+ file0
+
+
+ line276
+ col30
+ file0
+
+
end
Index: test/Analysis/diagnostics/dtors.cpp
===================================================================
--- test/Analysis/diagnostics/dtors.cpp
+++ test/Analysis/diagnostics/dtors.cpp
@@ -17,9 +17,10 @@
smart_ptr(S *);
S *get() {
return (x || 0) ? nullptr : s; // expected-note{{Left side of '||' is false}}
- // expected-note@-1{{'?' condition is false}}
- // expected-warning@-2{{Use of memory after it is freed}}
- // expected-note@-3{{Use of memory after it is freed}}
+ // expected-note@-1{{Assuming the condition is false}}
+ // expected-note@-2{{'?' condition is false}}
+ // expected-warning@-3{{Use of memory after it is freed}}
+ // expected-note@-4{{Use of memory after it is freed}}
}
};
Index: test/Analysis/diagnostics/macros.cpp
===================================================================
--- test/Analysis/diagnostics/macros.cpp
+++ test/Analysis/diagnostics/macros.cpp
@@ -30,7 +30,8 @@
// There are no path notes on the comparison to float types.
void testDoubleMacro(double d) {
- if (d == DBL_MAX) { // expected-note {{Taking true branch}}
+ if (d == DBL_MAX) { // expected-note {{Assuming 'd' is equal to DBL_MAX}}
+ // expected-note@-1 {{Taking true branch}}
char *p = NULL; // expected-note {{'p' initialized to a null pointer value}}
*p = 7; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
Index: test/Analysis/uninit-vals.m
===================================================================
--- test/Analysis/uninit-vals.m
+++ test/Analysis/uninit-vals.m
@@ -164,7 +164,8 @@
// expected-note@-1{{TRUE}}
testObj->origin = makePoint(0.0, 0.0);
- if (testObj->size > 0) { ; } // expected-note{{Taking false branch}}
+ if (testObj->size > 0) { ; } // expected-note{{Assuming the condition is false}}
+ // expected-note@-1{{Taking false branch}}
// FIXME: Assigning to 'testObj->origin' kills the default binding for the
// whole region, meaning that we've forgotten that testObj->size should also
@@ -218,10 +219,14 @@
// expected-note@-1{{TRUE}}
testObj->origin = makeIntPoint(1, 2);
- if (testObj->size > 0) { ; } // expected-note{{Taking false branch}}
+ if (testObj->size > 0) { ; } // expected-note{{Assuming the condition is false}}
// expected-note@-1{{Taking false branch}}
- // expected-note@-2{{Taking false branch}}
+ // expected-note@-2{{Assuming the condition is false}}
// expected-note@-3{{Taking false branch}}
+ // expected-note@-4{{Assuming the condition is false}}
+ // expected-note@-5{{Taking false branch}}
+ // expected-note@-6{{Assuming the condition is false}}
+ // expected-note@-7{{Taking false branch}}
// FIXME: Assigning to 'testObj->origin' kills the default binding for the
// whole region, meaning that we've forgotten that testObj->size should also