35class ConstraintBasedEQEvaluator {
43 : CompareValue(CompareValue), PS(
C.getState()), SVB(
C.getSValBuilder()) {}
45 bool operator()(
const llvm::APSInt &EnumDeclInitValue) {
48 SVB.
evalEQ(PS, EnumDeclValue, CompareValue);
50 return static_cast<bool>(PS->assume(ElemEqualsValueToCast,
true));
60class EnumCastOutOfRangeChecker :
public Checker<check::PreStmt<CastExpr>> {
61 mutable std::unique_ptr<BugType> EnumValueCastOutOfRange;
72EnumValueVector getDeclValuesForEnum(
const EnumDecl *ED) {
73 EnumValueVector DeclValues(
75 llvm::transform(ED->
enumerators(), DeclValues.begin(),
84 assert(E &&
"valid EnumDecl* is expected");
86 if (!EnumValueCastOutOfRange)
87 EnumValueCastOutOfRange.reset(
88 new BugType(
this,
"Enum cast out of range"));
91 "not in the valid range of values for "};
92 StringRef EnumName{E->
getName()};
93 if (EnumName.empty()) {
101 auto BR = std::make_unique<PathSensitiveBugReport>(*EnumValueCastOutOfRange,
104 BR->addNote(
"enum declared here",
106 {E->getSourceRange()});
107 C.emitReport(std::move(BR));
111void EnumCastOutOfRangeChecker::checkPreStmt(
const CastExpr *CE,
121 case CK_IntegralCast:
130 const std::optional<DefinedOrUnknownSVal> ValueToCast =
149 EnumValueVector DeclValues = getDeclValuesForEnum(ED);
155 if (DeclValues.size() == 0)
159 bool PossibleValueMatch =
160 llvm::any_of(DeclValues, ConstraintBasedEQEvaluator(
C, *ValueToCast));
164 if (!PossibleValueMatch)
165 reportWarning(
C, CE, ED);
168void ento::registerEnumCastOutOfRangeChecker(
CheckerManager &mgr) {
172bool ento::shouldRegisterEnumCastOutOfRangeChecker(
const CheckerManager &mgr) {
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
An instance of this object exists for each enum constant that is defined.
enumerator_range enumerators() const
enumerator_iterator enumerator_begin() const
enumerator_iterator enumerator_end() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A (possibly-)qualified type.
const T * castAs() const
Member-template castAs<specific type>.
bool isEnumeralType() const
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
SVal evalEQ(ProgramStateRef state, SVal lhs, SVal rhs)
bool trackExpressionValue(const ExplodedNode *N, const Expr *E, PathSensitiveBugReport &R, TrackingOptions Opts={})
Attempts to add visitors to track expression value back to its point of origin.