Index: include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h @@ -79,6 +79,10 @@ ConstraintManager() = default; virtual ~ConstraintManager(); + /// Return true if the constraints are changed between two program states. + virtual bool isConstraintChanged(ProgramStateRef S1, + ProgramStateRef S2) const = 0; + virtual ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond, bool Assumption) = 0; Index: include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h @@ -217,6 +217,11 @@ OS << nl; } + bool isConstraintChanged(ProgramStateRef S1, + ProgramStateRef S2) const override { + return S1->get() != S2->get(); + } + bool canReasonAbout(SVal X) const override { const TargetInfo &TI = getBasicVals().getContext().getTargetInfo(); Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1789,13 +1789,11 @@ BugReporterContext &BRC, BugReport &BR) { ProgramPoint progPoint = N->getLocation(); ProgramStateRef CurrentState = N->getState(); - ProgramStateRef PrevState = N->getFirstPred()->getState(); + ProgramStateRef PreviousState = N->getFirstPred()->getState(); - // Compare the GDMs of the state, because that is where constraints - // are managed. Note that ensure that we only look at nodes that - // were generated by the analyzer engine proper, not checkers. - if (CurrentState->getGDM().getRoot() == - PrevState->getGDM().getRoot()) + // If the constraint information does not changed there is no assumption. + if (!BRC.getStateManager().getConstraintManager().isConstraintChanged( + CurrentState, PreviousState)) return nullptr; // If an assumption was made on a branch, it should be caught Index: lib/StaticAnalyzer/Core/RangeConstraintManager.cpp =================================================================== --- lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -230,6 +230,11 @@ // Implementation for interface from ConstraintManager. //===------------------------------------------------------------------===// + bool isConstraintChanged(ProgramStateRef S1, + ProgramStateRef S2) const override { + return S1->get() != S2->get(); + } + bool canReasonAbout(SVal X) const override; ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;