32 using namespace clang;
36 class ConversionChecker :
public Checker<check::PreStmt<ImplicitCastExpr>> {
41 mutable std::unique_ptr<BuiltinBug> BT;
71 bool LossOfSign =
false;
72 bool LossOfPrecision =
false;
75 if (
const auto *B = dyn_cast<BinaryOperator>(Parent)) {
77 if (Opc == BO_Assign) {
78 LossOfSign = isLossOfSign(Cast, C);
79 LossOfPrecision = isLossOfPrecision(Cast, Cast->
getType(), C);
80 }
else if (Opc == BO_AddAssign || Opc == BO_SubAssign) {
82 LossOfPrecision = isLossOfPrecision(Cast, B->getLHS()->
getType(), C);
83 }
else if (Opc == BO_MulAssign) {
84 LossOfSign = isLossOfSign(Cast, C);
85 LossOfPrecision = isLossOfPrecision(Cast, B->getLHS()->
getType(), C);
86 }
else if (Opc == BO_DivAssign || Opc == BO_RemAssign) {
87 LossOfSign = isLossOfSign(Cast, C);
89 }
else if (Opc == BO_AndAssign) {
90 LossOfSign = isLossOfSign(Cast, C);
92 }
else if (Opc == BO_OrAssign || Opc == BO_XorAssign) {
93 LossOfSign = isLossOfSign(Cast, C);
94 LossOfPrecision = isLossOfPrecision(Cast, B->getLHS()->
getType(), C);
95 }
else if (B->isRelationalOp() || B->isMultiplicativeOp()) {
96 LossOfSign = isLossOfSign(Cast, C);
98 }
else if (isa<DeclStmt>(Parent)) {
99 LossOfSign = isLossOfSign(Cast, C);
100 LossOfPrecision = isLossOfPrecision(Cast, Cast->
getType(), C);
103 if (LossOfSign || LossOfPrecision) {
109 reportBug(N, C,
"Loss of sign in implicit conversion");
111 reportBug(N, C,
"Loss of precision in implicit conversion");
116 const char Msg[])
const {
119 new BuiltinBug(
this,
"Conversion",
"Possible loss of sign/precision."));
122 auto R = llvm::make_unique<BugReport>(*BT, Msg, N);
143 if (W == 1 || W >= 64U)
146 unsigned long long MaxVal = 1ULL << W;
A (possibly-)qualified type.
Stmt - This represents one statement.
Stmt * getParent(Stmt *) const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isGreaterOrEqual(const Expr *E, unsigned long long Val)
Returns true if the value of E is greater than or equal to Val under unsigned comparison.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], or an enum decl which has a signed representation.
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
ParentMap & getParentMap() const
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Dataflow Directional Tag Classes.
ASTContext & getASTContext()
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
unsigned getIntWidth(QualType T) const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const ProgramStateRef & getState() const
bool isNegative(const Expr *E)
Returns true if the value of E is negative.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
const LocationContext * getLocationContext() const