Expand Up
@@ -10168,15 +10168,23 @@ namespace {
/// Structure recording the 'active' range of an integer-valued
/// expression.
struct IntRange {
/// The number of bits active in the int.
/// The number of bits active in the int. Note that this includes exactly one
/// sign bit if !NonNegative.
unsigned Width;
/// True if the int is known not to have negative values.
/// True if the int is known not to have negative values. If so, all leading
/// bits before Width are known zero, otherwise they are known to be the
/// same as the MSB within Width.
bool NonNegative;
IntRange(unsigned Width, bool NonNegative)
: Width(Width), NonNegative(NonNegative) {}
/// Number of bits excluding the sign bit.
unsigned valueBits() const {
return NonNegative ? Width : Width - 1;
}
/// Returns the range of the bool type.
static IntRange forBoolType() {
return IntRange(1, true);
Expand Down
Expand Up
@@ -10260,14 +10268,63 @@ struct IntRange {
/// Returns the supremum of two ranges: i.e. their conservative merge.
static IntRange join(IntRange L, IntRange R) {
return IntRange(std::max(L.Width, R.Width),
bool Unsigned = L.NonNegative && R.NonNegative;
return IntRange(std::max(L.valueBits(), R.valueBits()) + !Unsigned,
L.NonNegative && R.NonNegative);
}
/// Returns the infinum of two ranges: i.e. their aggressive merge.
static IntRange meet(IntRange L, IntRange R) {
return IntRange(std::min(L.Width, R.Width),
L.NonNegative || R.NonNegative);
/// Return the range of a bitwise-AND of the two ranges.
static IntRange bit_and(IntRange L, IntRange R) {
unsigned Bits = std::max(L.Width, R.Width);
bool NonNegative = false;
if (L.NonNegative) {
Bits = std::min(Bits, L.Width);
NonNegative = true;
}
if (R.NonNegative) {
Bits = std::min(Bits, R.Width);
NonNegative = true;
}
return IntRange(Bits, NonNegative);
}
/// Return the range of a sum of the two ranges.
static IntRange sum(IntRange L, IntRange R) {
bool Unsigned = L.NonNegative && R.NonNegative;
return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !Unsigned,
Unsigned);
}
/// Return the range of a difference of the two ranges.
static IntRange difference(IntRange L, IntRange R) {
// We need a 1-bit-wider range if:
// 1) LHS can be negative: least value can be reduced.
// 2) RHS can be negative: greatest value can be increased.
bool CanWiden = !L.NonNegative || !R.NonNegative;
bool Unsigned = L.NonNegative && R.Width == 0;
return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
!Unsigned,
Unsigned);
}
/// Return the range of a product of the two ranges.
static IntRange product(IntRange L, IntRange R) {
// If both LHS and RHS can be negative, we can form
// -2^L * -2^R = 2^(L + R)
// which requires L + R + 1 value bits to represent.
bool CanWiden = !L.NonNegative && !R.NonNegative;
bool Unsigned = L.NonNegative && R.NonNegative;
return IntRange(L.valueBits() + R.valueBits() + CanWiden + !Unsigned,
Unsigned);
}
/// Return the range of a remainder operation between the two ranges.
static IntRange rem(IntRange L, IntRange R) {
// The result of a remainder can't be larger than the result of
// either side. The sign of the result is the sign of the LHS.
bool Unsigned = L.NonNegative;
return IntRange(std::min(L.valueBits(), R.valueBits()) + !Unsigned,
Unsigned);
}
};
Expand Down
Expand Up
@@ -10325,9 +10382,13 @@ static QualType GetExprType(const Expr *E) {
/// Pseudo-evaluate the given integer expression, estimating the
/// range of values it might take.
///
/// \param MaxWidth - the width to which the value will be truncated
/// \param MaxWidth The width to which the value will be truncated.
/// \param Approximate If \c true, return a likely range for the result: in
/// particular, assume that aritmetic on narrower types doesn't leave
/// those types. If \c false, return a range including all possible
/// result values.
static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
bool InConstantContext) {
bool InConstantContext, bool Approximate ) {
E = E->IgnoreParens();
// Try a full evaluation first.
Expand All
@@ -10340,7 +10401,8 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
// being of the new, wider type.
if (const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
return GetExprRange(C, CE->getSubExpr(), MaxWidth, InConstantContext);
return GetExprRange(C, CE->getSubExpr(), MaxWidth, InConstantContext,
Approximate);
IntRange OutputTypeRange = IntRange::forValueOfType(C, GetExprType(CE));
Expand All
@@ -10353,7 +10415,7 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
IntRange SubRange = GetExprRange(C, CE->getSubExpr(),
std::min(MaxWidth, OutputTypeRange.Width),
InConstantContext);
InConstantContext, Approximate );
// Bail out if the subexpr's range is as wide as the cast type.
if (SubRange.Width >= OutputTypeRange.Width)
Expand All
@@ -10371,23 +10433,25 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
if (CO->getCond()->EvaluateAsBooleanCondition(CondResult, C))
return GetExprRange(C,
CondResult ? CO->getTrueExpr() : CO->getFalseExpr(),
MaxWidth, InConstantContext);
MaxWidth, InConstantContext, Approximate );
// Otherwise, conservatively merge.
// GetExprRange requires an integer expression, but a throw expression
// results in a void type.
Expr *E = CO->getTrueExpr();
IntRange L = E->getType()->isVoidType()
? IntRange{0, true}
: GetExprRange(C, E, MaxWidth, InConstantContext);
: GetExprRange(C, E, MaxWidth, InConstantContext, Approximate );
E = CO->getFalseExpr();
IntRange R = E->getType()->isVoidType()
? IntRange{0, true}
: GetExprRange(C, E, MaxWidth, InConstantContext);
: GetExprRange(C, E, MaxWidth, InConstantContext, Approximate );
return IntRange::join(L, R);
}
if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
switch (BO->getOpcode()) {
case BO_Cmp:
llvm_unreachable("builtin <=> should have class type");
Expand Down
Expand Up
@@ -10419,7 +10483,8 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
// been coerced to the LHS type.
case BO_Assign:
// TODO: bitfields?
return GetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext);
return GetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext,
Approximate);
// Operations with opaque sources are black-listed.
case BO_PtrMemD:
Expand All
@@ -10429,9 +10494,8 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
// Bitwise-and uses the *infinum* of the two source ranges.
case BO_And:
case BO_AndAssign:
return IntRange::meet(
GetExprRange(C, BO->getLHS(), MaxWidth, InConstantContext),
GetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext));
Combine = IntRange::bit_and;
break;
// Left shift gets black-listed based on a judgement call.
case BO_Shl:
Expand All
@@ -10452,7 +10516,8 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
// Right shift by a constant can narrow its left argument.
case BO_Shr:
case BO_ShrAssign: {
IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth, InConstantContext);
IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth, InConstantContext,
Approximate);
// If the shift amount is a positive constant, drop the width by
// that much.
Expand All
@@ -10472,20 +10537,33 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
// Comma acts as its right operand.
case BO_Comma:
return GetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext);
return GetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext,
Approximate);
case BO_Add:
if (!Approximate)
Combine = IntRange::sum;
break;
// Black-list pointer subtractions.
case BO_Sub:
if (BO->getLHS()->getType()->isPointerType())
return IntRange::forValueOfType(C, GetExprType(E));
if (!Approximate)
Combine = IntRange::difference;
break;
case BO_Mul:
if (!Approximate)
Combine = IntRange::product;
break;
// The width of a division result is mostly determined by the size
// of the LHS.
case BO_Div: {
// Don't 'pre-truncate' the operands.
unsigned opWidth = C.getIntWidth(GetExprType(E));
IntRange L = GetExprRange(C, BO->getLHS(), opWidth, InConstantContext);
IntRange L = GetExprRange(C, BO->getLHS(), opWidth, InConstantContext,
Approximate);
// If the divisor is constant, use that.
if (Optional<llvm::APSInt> divisor =
Expand All
@@ -10499,36 +10577,35 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
}
// Otherwise, just use the LHS's width.
IntRange R = GetExprRange(C, BO->getRHS(), opWidth, InConstantContext);
// FIXME: This is wrong if the LHS could be its minimal value and the RHS
// could be -1.
IntRange R = GetExprRange(C, BO->getRHS(), opWidth, InConstantContext,
Approximate);
return IntRange(L.Width, L.NonNegative && R.NonNegative);
}
// The result of a remainder can't be larger than the result of
// either side.
case BO_Rem: {
// Don't 'pre-truncate' the operands.
unsigned opWidth = C.getIntWidth(GetExprType(E));
IntRange L = GetExprRange(C, BO->getLHS(), opWidth, InConstantContext);
IntRange R = GetExprRange(C, BO->getRHS(), opWidth, InConstantContext);
IntRange meet = IntRange::meet(L, R);
meet.Width = std::min(meet.Width, MaxWidth);
return meet;
}
case BO_Rem:
Combine = IntRange::rem;
break;
// The default behavior is okay for these.
case BO_Mul:
case BO_Add:
case BO_Xor:
case BO_Or:
break;
}
// The default case is to treat the operation as if it were closed
// on the narrowest type that encompasses both operands.
IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth, InConstantContext);
IntRange R = GetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext);
return IntRange::join(L, R);
// Combine the two ranges, but limit the result to the type in which we
// performed the computation.
QualType T = GetExprType(E);
unsigned opWidth = C.getIntWidth(T);
IntRange L =
GetExprRange(C, BO->getLHS(), opWidth, InConstantContext, Approximate);
IntRange R =
GetExprRange(C, BO->getRHS(), opWidth, InConstantContext, Approximate);
IntRange C = Combine(L, R);
C.NonNegative |= T->isUnsignedIntegerOrEnumerationType();
C.Width = std::min(C.Width, MaxWidth);
return C;
}
if (const auto *UO = dyn_cast<UnaryOperator>(E)) {
Expand All
@@ -10543,12 +10620,14 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
return IntRange::forValueOfType(C, GetExprType(E));
default:
return GetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext);
return GetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,
Approximate);
}
}
if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
return GetExprRange(C, OVE->getSourceExpr(), MaxWidth, InConstantContext);
return GetExprRange(C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
Approximate);
if (const auto *BitField = E->getSourceBitField())
return IntRange(BitField->getBitWidthValue(C),
Expand All
@@ -10558,8 +10637,9 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth,
}
static IntRange GetExprRange(ASTContext &C, const Expr *E,
bool InConstantContext) {
return GetExprRange(C, E, C.getIntWidth(GetExprType(E)), InConstantContext);
bool InConstantContext, bool Approximate) {
return GetExprRange(C, E, C.getIntWidth(GetExprType(E)), InConstantContext,
Approximate);
}
/// Checks whether the given value, which currently has the given
Expand Down
Expand Up
@@ -10804,8 +10884,8 @@ static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E,
S.Context.hasSameUnqualifiedType(Constant->getType(), Other->getType()))
return false;
IntRange OtherValueRange =
GetExprRange( S.Context, Other, S.isConstantEvaluated());
IntRange OtherValueRange = GetExprRange(
S.Context, Other, S.isConstantEvaluated(), /*Approximate*/ false );
QualType OtherT = Other->getType();
if (const auto *AT = OtherT->getAs<AtomicType>())
Expand Down
Expand Up
@@ -10849,6 +10929,11 @@ static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E,
}
}
// Don't warn if the non-constant operand actually always evaluates to the
// same value.
if (!TautologicalTypeCompare && OtherValueRange.Width == 0)
return false;
// Suppress the diagnostic for an in-range comparison if the constant comes
// from a macro or enumerator. We don't want to diagnose
//
Expand All
@@ -10859,6 +10944,12 @@ static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E,
if (InRange && IsEnumConstOrFromMacro(S, Constant))
return false;
// A comparison of an unsigned bit-field against 0 is really a type problem,
// even though at the type level the bit-field might promote to 'signed int'.
if (Other->refersToBitField() && InRange && Value == 0 &&
Other->getType()->isUnsignedIntegerOrEnumerationType())
TautologicalTypeCompare = true;
// If this is a comparison to an enum constant, include that
// constant in the diagnostic.
const EnumConstantDecl *ED = nullptr;
Expand Down
Expand Up
@@ -11004,8 +11095,8 @@ static void AnalyzeComparison(Sema &S, BinaryOperator *E) {
}
// Otherwise, calculate the effective range of the signed operand.
IntRange signedRange =
GetExprRange( S.Context, signedOperand, S.isConstantEvaluated());
IntRange signedRange = GetExprRange(
S.Context, signedOperand, S.isConstantEvaluated(), /*Approximate*/ true );
// Go ahead and analyze implicit conversions in the operands. Note
// that we skip the implicit conversions on both sides.
Expand All
@@ -11023,7 +11114,8 @@ static void AnalyzeComparison(Sema &S, BinaryOperator *E) {
if (E->isEqualityOp()) {
unsigned comparisonWidth = S.Context.getIntWidth(T);
IntRange unsignedRange =
GetExprRange(S.Context, unsignedOperand, S.isConstantEvaluated());
GetExprRange(S.Context, unsignedOperand, S.isConstantEvaluated(),
/*Approximate*/ true);
// We should never be unable to prove that the unsigned operand is
// non-negative.
Expand Down
Expand Up
@@ -11906,7 +11998,8 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
if (SourceBT && TargetBT && SourceBT->isIntegerType() &&
TargetBT->isFloatingType() && !IsListInit) {
// Determine the number of precision bits in the source integer type.
IntRange SourceRange = GetExprRange(S.Context, E, S.isConstantEvaluated());
IntRange SourceRange = GetExprRange(S.Context, E, S.isConstantEvaluated(),
/*Approximate*/ true);
unsigned int SourcePrecision = SourceRange.Width;
// Determine the number of precision bits in the
Expand Down
Expand Up
@@ -11971,10 +12064,13 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
<< E->getType());
}
IntRange SourceRange = GetExprRange(S.Context, E, S.isConstantEvaluated());
IntRange MinSourceRange =
GetExprRange(S.Context, E, S.isConstantEvaluated(), /*Approximate*/ true);
IntRange MaxSourceRange =
GetExprRange(S.Context, E, S.isConstantEvaluated(), /*Approximate*/ false);
IntRange TargetRange = IntRange::forTargetOfCanonicalType(S.Context, Target);
if (SourceRange .Width > TargetRange.Width) {
if (MinSourceRange .Width > TargetRange.Width) {
// If the source is a constant, use a default-on diagnostic.
// TODO: this should happen for bitfield stores, too.
Expr::EvalResult Result;
Expand All
@@ -11993,7 +12089,7 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
E->getExprLoc(), E,
S.PDiag(diag::warn_impcast_integer_precision_constant)
<< PrettySourceValue << PrettyTargetValue << E->getType() << T
<< E->getSourceRange() << clang:: SourceRange(CC));
<< E->getSourceRange() << SourceRange(CC));
return;
}
Expand All
@@ -12007,7 +12103,9 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_precision);
}
if (TargetRange.Width > SourceRange.Width) {
// Only warn here if E can't possibly reach the target range, not only if
// it's not likely to be in that range.
if (TargetRange.Width > MaxSourceRange.Width) {
if (auto *UO = dyn_cast<UnaryOperator>(E))
if (UO->getOpcode() == UO_Minus)
if (Source->isUnsignedIntegerType()) {
Expand All
@@ -12020,8 +12118,8 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
}
}
if (TargetRange.Width == SourceRange .Width && !TargetRange.NonNegative &&
SourceRange .NonNegative && Source->isSignedIntegerType()) {
if (TargetRange.Width == MinSourceRange .Width && !TargetRange.NonNegative &&
MinSourceRange .NonNegative && Source->isSignedIntegerType()) {
// Warn when doing a signed to signed conversion, warn if the positive
// source value is exactly the width of the target type, which will
// cause a negative value to be stored.
Expand All
@@ -12038,17 +12136,17 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
E->getExprLoc(), E,
S.PDiag(diag::warn_impcast_integer_precision_constant)
<< PrettySourceValue << PrettyTargetValue << E->getType() << T
<< E->getSourceRange() << clang:: SourceRange(CC));
<< E->getSourceRange() << SourceRange(CC));
return;
}
}
// Fall through for non-constants to give a sign conversion warning.
}
if ((TargetRange.NonNegative && !SourceRange .NonNegative) ||
(!TargetRange.NonNegative && SourceRange .NonNegative &&
SourceRange .Width == TargetRange.Width)) {
if ((TargetRange.NonNegative && !MinSourceRange .NonNegative) ||
(!TargetRange.NonNegative && MinSourceRange .NonNegative &&
MinSourceRange .Width == TargetRange.Width)) {
if (S.SourceMgr.isInSystemMacro(CC))
return;
Expand Down