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