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);
128 unsigned long long Val) {
151 return StGE && !StLT;
166 Bldr.evalBinOp(State, BO_LT, DefinedEVal, V, Bldr.getConditionType());
171 std::tie(StNegative, StPositive) =
174 return StNegative && !StPositive;
194 if (W == 1 || W >= 64U)
197 unsigned long long MaxVal = 1ULL << W;
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
A (possibly-)qualified type.
Stmt - This represents one statement.
unsigned getIntWidth(QualType T) const
virtual SVal getBinding(Store store, Loc loc, QualType T=QualType())=0
Return the value bound to specified location in a given state.
ProgramStateManager & getStateManager()
bool isUnknownOrUndef() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond)
Returns a pair of states (StTrue, StFalse) where the given condition is assumed to be true or false...
Expr - This represents one expression.
const ProgramStateRef & getState() const
static bool isGreaterEqual(CheckerContext &C, const Expr *E, unsigned long long Val)
ParentMap & getParentMap() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
StoreManager & getStoreManager()
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
QualType getConditionType() const
ConstraintManager & getConstraintManager()
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
Stmt * getParent(Stmt *) const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
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...
ASTContext & getASTContext()
static bool isNegative(CheckerContext &C, const Expr *E)
detail::InMemoryDirectory::const_iterator E
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
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...
SValBuilder & getSValBuilder()
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.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const LocationContext * getLocationContext() const
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.