25#include "llvm/Support/FormatVariadic.h"
37class ConstraintBasedEQEvaluator {
45 : CompareValue(CompareValue), PS(
C.getState()), SVB(
C.getSValBuilder()) {}
47 bool operator()(
const llvm::APSInt &EnumDeclInitValue) {
50 SVB.
evalEQ(PS, EnumDeclValue, CompareValue);
52 return static_cast<bool>(PS->assume(ElemEqualsValueToCast,
true));
62class EnumCastOutOfRangeChecker :
public Checker<check::PreStmt<CastExpr>> {
63 const BugType EnumValueCastOutOfRange{
this,
"Enum cast out of range"};
74EnumValueVector getDeclValuesForEnum(
const EnumDecl *ED) {
75 EnumValueVector DeclValues(
77 llvm::transform(ED->
enumerators(), DeclValues.begin(),
86 assert(
E &&
"valid EnumDecl* is expected");
88 std::string ValueStr =
"", NameStr =
"the enum";
91 const auto ConcreteValue =
94 ValueStr = formatv(
" '{0}'", ConcreteValue->getValue());
96 if (StringRef EnumName{
E->getName()}; !EnumName.empty()) {
97 NameStr = formatv(
"'{0}'", EnumName);
100 std::string Msg = formatv(
"The value{0} provided to the cast expression is "
101 "not in the valid range of values for {1}",
104 auto BR = std::make_unique<PathSensitiveBugReport>(EnumValueCastOutOfRange,
107 BR->addNote(
"enum declared here",
109 {E->getSourceRange()});
110 C.emitReport(std::move(BR));
114void EnumCastOutOfRangeChecker::checkPreStmt(
const CastExpr *CE,
124 case CK_IntegralCast:
133 const std::optional<DefinedOrUnknownSVal> ValueToCast =
152 EnumValueVector DeclValues = getDeclValuesForEnum(ED);
161 if (DeclValues.size() == 0)
165 bool PossibleValueMatch =
166 llvm::any_of(DeclValues, ConstraintBasedEQEvaluator(
C, *ValueToCast));
170 if (!PossibleValueMatch)
171 reportWarning(
C, CE, ED);
174void ento::registerEnumCastOutOfRangeChecker(
CheckerManager &mgr) {
178bool 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.
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)
Value representing integer constant.
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.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T