Index: include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -124,7 +124,12 @@ SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type); - + + /// \return Whether values in \p lhs and \p rhs are equal at \p state. + bool areEqual(ProgramStateRef state, SVal lhs, SVal rhs); + + SVal evalEQ(ProgramStateRef state, SVal lhs, SVal rhs); + DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs, DefinedOrUnknownSVal rhs); Index: lib/StaticAnalyzer/Core/SValBuilder.cpp =================================================================== --- lib/StaticAnalyzer/Core/SValBuilder.cpp +++ lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -413,10 +413,18 @@ type); } +bool SValBuilder::areEqual(ProgramStateRef state, SVal lhs, SVal rhs) { + return !state->isNull(evalEQ(state, lhs, rhs)).isConstrainedTrue(); +} + +SVal SValBuilder::evalEQ(ProgramStateRef state, SVal lhs, SVal rhs) { + return evalBinOp(state, BO_EQ, lhs, rhs, getConditionType()); +} + DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs, DefinedOrUnknownSVal rhs) { - return evalBinOp(state, BO_EQ, lhs, rhs, getConditionType()) + return evalEQ(state, static_cast(lhs), static_cast(rhs)) .castAs(); }