return IntRange(MaxWidth, Ty->isUnsignedIntegerOrEnumerationType());
}
+static QualType GetExprType(Expr *E) {
+ QualType Ty = E->getType();
+ if (const AtomicType *AtomicRHS = Ty->getAs<AtomicType>())
+ Ty = AtomicRHS->getValueType();
+ return Ty;
+}
+
/// Pseudo-evaluate the given integer expression, estimating the
/// range of values it might take.
///
// Try a full evaluation first.
Expr::EvalResult result;
if (E->EvaluateAsRValue(result, C))
- return GetValueRange(C, result.Val, E->getType(), MaxWidth);
+ return GetValueRange(C, result.Val, GetExprType(E), MaxWidth);
// I think we only want to look through implicit casts here; if the
// user has an explicit widening cast, we should treat the value as
if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
return GetExprRange(C, CE->getSubExpr(), MaxWidth);
- IntRange OutputTypeRange = IntRange::forValueOfType(C, CE->getType());
+ IntRange OutputTypeRange = IntRange::forValueOfType(C, GetExprType(CE));
bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast);
case BO_XorAssign:
case BO_OrAssign:
// TODO: bitfields?
- return IntRange::forValueOfType(C, E->getType());
+ return IntRange::forValueOfType(C, GetExprType(E));
// Simple assignments just pass through the RHS, which will have
// been coerced to the LHS type.
// Operations with opaque sources are black-listed.
case BO_PtrMemD:
case BO_PtrMemI:
- return IntRange::forValueOfType(C, E->getType());
+ return IntRange::forValueOfType(C, GetExprType(E));
// Bitwise-and uses the *infinum* of the two source ranges.
case BO_And:
if (IntegerLiteral *I
= dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
if (I->getValue() == 1) {
- IntRange R = IntRange::forValueOfType(C, E->getType());
+ IntRange R = IntRange::forValueOfType(C, GetExprType(E));
return IntRange(R.Width, /*NonNegative*/ true);
}
}
// fallthrough
case BO_ShlAssign:
- return IntRange::forValueOfType(C, E->getType());
+ return IntRange::forValueOfType(C, GetExprType(E));
// Right shift by a constant can narrow its left argument.
case BO_Shr:
// Black-list pointer subtractions.
case BO_Sub:
if (BO->getLHS()->getType()->isPointerType())
- return IntRange::forValueOfType(C, E->getType());
+ return IntRange::forValueOfType(C, GetExprType(E));
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(E->getType());
+ unsigned opWidth = C.getIntWidth(GetExprType(E));
IntRange L = GetExprRange(C, BO->getLHS(), opWidth);
// If the divisor is constant, use that.
// either side.
case BO_Rem: {
// Don't 'pre-truncate' the operands.
- unsigned opWidth = C.getIntWidth(E->getType());
+ unsigned opWidth = C.getIntWidth(GetExprType(E));
IntRange L = GetExprRange(C, BO->getLHS(), opWidth);
IntRange R = GetExprRange(C, BO->getRHS(), opWidth);
// Operations with opaque sources are black-listed.
case UO_Deref:
case UO_AddrOf: // should be impossible
- return IntRange::forValueOfType(C, E->getType());
+ return IntRange::forValueOfType(C, GetExprType(E));
default:
return GetExprRange(C, UO->getSubExpr(), MaxWidth);
}
}
-
- if (dyn_cast<OffsetOfExpr>(E)) {
- IntRange::forValueOfType(C, E->getType());
- }
if (FieldDecl *BitField = E->getSourceBitField())
return IntRange(BitField->getBitWidthValue(C),
BitField->getType()->isUnsignedIntegerOrEnumerationType());
- return IntRange::forValueOfType(C, E->getType());
+ return IntRange::forValueOfType(C, GetExprType(E));
}
static IntRange GetExprRange(ASTContext &C, Expr *E) {
- return GetExprRange(C, E, C.getIntWidth(E->getType()));
+ return GetExprRange(C, E, C.getIntWidth(GetExprType(E)));
}
/// Checks whether the given value, which currently has the given
Cond = UsualUnaryConversions(Cond.take());
if (Cond.isInvalid())
return QualType();
- LHS = UsualUnaryConversions(LHS.take());
- if (LHS.isInvalid())
- return QualType();
- RHS = UsualUnaryConversions(RHS.take());
- if (RHS.isInvalid())
+ UsualArithmeticConversions(LHS, RHS);
+ if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
QualType CondTy = Cond.get()->getType();
// If both operands have arithmetic type, do the usual arithmetic conversions
// to find a common type: C99 6.5.15p3,5.
- if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) {
- UsualArithmeticConversions(LHS, RHS);
- if (LHS.isInvalid() || RHS.isInvalid())
- return QualType();
+ if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType())
return LHS.get()->getType();
- }
// If both operands are the same structure or union type, the result is that
// type.
}
// C99 6.5.8p3 / C99 6.5.9p4
- if (LHS.get()->getType()->isArithmeticType() &&
- RHS.get()->getType()->isArithmeticType()) {
- UsualArithmeticConversions(LHS, RHS);
- if (LHS.isInvalid() || RHS.isInvalid())
- return QualType();
- }
- else {
- LHS = UsualUnaryConversions(LHS.take());
- if (LHS.isInvalid())
- return QualType();
-
- RHS = UsualUnaryConversions(RHS.take());
- if (RHS.isInvalid())
- return QualType();
- }
+ UsualArithmeticConversions(LHS, RHS);
+ if (LHS.isInvalid() || RHS.isInvalid())
+ return QualType();
LHSType = LHS.get()->getType();
RHSType = RHS.get()->getType();