@@ -59,7 +59,7 @@ class ConstraintBasedEQEvaluator {
59
59
// value can be matching.
60
60
class EnumCastOutOfRangeChecker : public Checker <check::PreStmt<CastExpr>> {
61
61
mutable std::unique_ptr<BugType> EnumValueCastOutOfRange;
62
- void reportWarning (CheckerContext &C) const ;
62
+ void reportWarning (CheckerContext &C, const EnumDecl *E ) const ;
63
63
64
64
public:
65
65
void checkPreStmt (const CastExpr *CE, CheckerContext &C) const ;
@@ -72,21 +72,36 @@ EnumValueVector getDeclValuesForEnum(const EnumDecl *ED) {
72
72
EnumValueVector DeclValues (
73
73
std::distance (ED->enumerator_begin (), ED->enumerator_end ()));
74
74
llvm::transform (ED->enumerators (), DeclValues.begin (),
75
- [](const EnumConstantDecl *D) { return D->getInitVal (); });
75
+ [](const EnumConstantDecl *D) { return D->getInitVal (); });
76
76
return DeclValues;
77
77
}
78
78
} // namespace
79
79
80
- void EnumCastOutOfRangeChecker::reportWarning (CheckerContext &C) const {
80
+ void EnumCastOutOfRangeChecker::reportWarning (CheckerContext &C,
81
+ const EnumDecl *E) const {
82
+ assert (E && " valid EnumDecl* is expected" );
81
83
if (const ExplodedNode *N = C.generateNonFatalErrorNode ()) {
82
84
if (!EnumValueCastOutOfRange)
83
85
EnumValueCastOutOfRange.reset (
84
86
new BugType (this , " Enum cast out of range" ));
85
- constexpr llvm::StringLiteral Msg =
86
- " The value provided to the cast expression is not in the valid range"
87
- " of values for the enum" ;
88
- C.emitReport (std::make_unique<PathSensitiveBugReport>(
89
- *EnumValueCastOutOfRange, Msg, N));
87
+
88
+ llvm::SmallString<128 > Msg{" The value provided to the cast expression is "
89
+ " not in the valid range of values for " };
90
+ StringRef EnumName{E->getName ()};
91
+ if (EnumName.empty ()) {
92
+ Msg += " the enum" ;
93
+ } else {
94
+ Msg += ' \' ' ;
95
+ Msg += EnumName;
96
+ Msg += ' \' ' ;
97
+ }
98
+
99
+ auto BR = std::make_unique<PathSensitiveBugReport>(*EnumValueCastOutOfRange,
100
+ Msg, N);
101
+ BR->addNote (" enum declared here" ,
102
+ PathDiagnosticLocation::create (E, C.getSourceManager ()),
103
+ {E->getSourceRange ()});
104
+ C.emitReport (std::move (BR));
90
105
}
91
106
}
92
107
@@ -144,7 +159,7 @@ void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE,
144
159
// If there is no value that can possibly match any of the enum values, then
145
160
// warn.
146
161
if (!PossibleValueMatch)
147
- reportWarning (C);
162
+ reportWarning (C, ED );
148
163
}
149
164
150
165
void ento::registerEnumCastOutOfRangeChecker (CheckerManager &mgr) {
0 commit comments