[Sema] Add Sema checks for detecting large integer literals that

overflow Builtin.Int2048 and add tests for checking the
correctness of the diagnostics.
This commit is contained in:
Ravi Kandhadai
2018-05-21 18:36:07 -07:00
parent dc5827cf22
commit f1ff8a61a5
10 changed files with 190 additions and 31 deletions

View File

@@ -1179,7 +1179,44 @@ namespace {
auto protocol = CS.getTypeChecker().getLiteralProtocol(expr);
if (!protocol)
return nullptr;
// Make sure that MaxIntegerType is defined if it would used later
// during constraint solving (CSApply).
if (isa<IntegerLiteralExpr>(expr) ||
(isa<MagicIdentifierLiteralExpr>(expr) &&
dyn_cast<MagicIdentifierLiteralExpr>(expr)->isColumn())) {
auto maxIntType = CS.TC.getMaxIntegerType(CS.DC);
if (maxIntType.isNull()) {
CS.TC.diagnose(expr->getLoc(), diag::no_MaxBuiltinIntegerType_found);
return nullptr;
}
// In the case of integer literal, make sure that the literal value
// will fit within the bit width of the maximum integer type.
if (IntegerLiteralExpr *intLit = dyn_cast<IntegerLiteralExpr>(expr)) {
unsigned maxWidth =
maxIntType->castTo<BuiltinIntegerType>()->getGreatestWidth();
APInt magnitude = intLit->getRawMagnitude();
unsigned magWidth = magnitude.getActiveBits();
bool isNegative = intLit->isNegative();
// Compute the literal bit width in the signed two's complement form.
// This is generally one more than the magnitude width, but is the
// same when the literal is of the form -2^i (for some Nat `i`).
unsigned signedLitWidth =
(isNegative && (magnitude.countTrailingZeros() == magWidth - 1))
? magWidth
: (magWidth + 1);
if (signedLitWidth > maxWidth) { // overflow?
CS.TC.diagnose(expr->getLoc(),
diag::integer_literal_overflows_maxwidth, maxWidth,
signedLitWidth);
return nullptr;
}
}
}
auto tv = CS.createTypeVariable(CS.getConstraintLocator(expr),
TVO_PrefersSubtypeBinding);