aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/FileCheck/FileCheck.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/FileCheck/FileCheck.cpp')
-rw-r--r--llvm/lib/FileCheck/FileCheck.cpp230
1 files changed, 66 insertions, 164 deletions
diff --git a/llvm/lib/FileCheck/FileCheck.cpp b/llvm/lib/FileCheck/FileCheck.cpp
index dd20bd3..3e4514f 100644
--- a/llvm/lib/FileCheck/FileCheck.cpp
+++ b/llvm/lib/FileCheck/FileCheck.cpp
@@ -79,38 +79,42 @@ Expected<std::string> ExpressionFormat::getWildcardRegex() const {
Expected<std::string>
ExpressionFormat::getMatchingString(ExpressionValue IntegerValue) const {
- uint64_t AbsoluteValue;
- StringRef SignPrefix = IntegerValue.isNegative() ? "-" : "";
-
+ APInt IntValue = IntegerValue.getAPIntValue();
+ // Error out for values that cannot be represented by the appropriate 64-bit
+ // integer (e.g. int64_t for a signed format) to keep the getter of
+ // ExpressionValue as an APInt an NFC.
if (Value == Kind::Signed) {
- Expected<int64_t> SignedValue = IntegerValue.getSignedValue();
- if (!SignedValue)
- return SignedValue.takeError();
- if (*SignedValue < 0)
- AbsoluteValue = cantFail(IntegerValue.getAbsolute().getUnsignedValue());
- else
- AbsoluteValue = *SignedValue;
+ if (!IntValue.isSignedIntN(64))
+ return make_error<OverflowError>();
} else {
- Expected<uint64_t> UnsignedValue = IntegerValue.getUnsignedValue();
- if (!UnsignedValue)
- return UnsignedValue.takeError();
- AbsoluteValue = *UnsignedValue;
+ if (!IntValue.isIntN(64))
+ return make_error<OverflowError>();
}
- std::string AbsoluteValueStr;
+ unsigned Radix;
+ bool UpperCase = false;
+ SmallString<8> AbsoluteValueStr;
+ StringRef SignPrefix = IntValue.isNegative() ? "-" : "";
switch (Value) {
case Kind::Unsigned:
case Kind::Signed:
- AbsoluteValueStr = utostr(AbsoluteValue);
+ Radix = 10;
break;
case Kind::HexUpper:
+ UpperCase = true;
+ Radix = 16;
+ break;
case Kind::HexLower:
- AbsoluteValueStr = utohexstr(AbsoluteValue, Value == Kind::HexLower);
+ Radix = 16;
+ UpperCase = false;
break;
default:
return createStringError(std::errc::invalid_argument,
"trying to match value with invalid format");
}
+ IntValue.abs().toString(AbsoluteValueStr, Radix, /*Signed=*/false,
+ /*formatAsCLiteral=*/false,
+ /*UpperCase=*/UpperCase);
StringRef AlternateFormPrefix = AlternateForm ? StringRef("0x") : StringRef();
@@ -155,183 +159,81 @@ ExpressionFormat::valueFromStringRepr(StringRef StrVal,
return ExpressionValue(UnsignedValue);
}
-Expected<int64_t> ExpressionValue::getSignedValue() const {
- std::optional<int64_t> SignedValue = Value.trySExtValue();
- if (!SignedValue)
- return make_error<OverflowError>();
- return *SignedValue;
-}
-
-Expected<uint64_t> ExpressionValue::getUnsignedValue() const {
- std::optional<int64_t> UnsignedValue = Value.tryZExtValue();
- if (!UnsignedValue)
- return make_error<OverflowError>();
-
- return *UnsignedValue;
-}
-
-ExpressionValue ExpressionValue::getAbsolute() const {
- unsigned bitwidth = Value.getBitWidth();
- assert(!Value.isNegative() || Value.isSignedIntN(bitwidth - 1));
- return ExpressionValue(Value.abs().getZExtValue());
-}
-
Expected<ExpressionValue> llvm::operator+(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand) {
- if (LeftOperand.isNegative() && RightOperand.isNegative()) {
- int64_t LeftValue = cantFail(LeftOperand.getSignedValue());
- int64_t RightValue = cantFail(RightOperand.getSignedValue());
- std::optional<int64_t> Result = checkedAdd<int64_t>(LeftValue, RightValue);
- if (!Result)
- return make_error<OverflowError>();
-
- return ExpressionValue(*Result);
- }
-
- // (-A) + B == B - A.
- if (LeftOperand.isNegative())
- return RightOperand - LeftOperand.getAbsolute();
-
- // A + (-B) == A - B.
- if (RightOperand.isNegative())
- return LeftOperand - RightOperand.getAbsolute();
-
- // Both values are positive at this point.
- uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
- uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
- std::optional<uint64_t> Result =
- checkedAddUnsigned<uint64_t>(LeftValue, RightValue);
- if (!Result)
+ bool Overflow;
+ APInt Result = LeftOperand.getAPIntValue().sadd_ov(
+ RightOperand.getAPIntValue(), Overflow);
+ if (Overflow ||
+ (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1)))
return make_error<OverflowError>();
- return ExpressionValue(*Result);
+ if (Result.isNegative())
+ return ExpressionValue(Result.getSExtValue());
+ else
+ return ExpressionValue(Result.getZExtValue());
}
Expected<ExpressionValue> llvm::operator-(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand) {
- // Result will be negative and thus might underflow.
- if (LeftOperand.isNegative() && !RightOperand.isNegative()) {
- int64_t LeftValue = cantFail(LeftOperand.getSignedValue());
- uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
- // Result <= -1 - (max int64_t) which overflows on 1- and 2-complement.
- if (RightValue > (uint64_t)std::numeric_limits<int64_t>::max())
- return make_error<OverflowError>();
- std::optional<int64_t> Result =
- checkedSub(LeftValue, static_cast<int64_t>(RightValue));
- if (!Result)
- return make_error<OverflowError>();
-
- return ExpressionValue(*Result);
- }
-
- // (-A) - (-B) == B - A.
- if (LeftOperand.isNegative())
- return RightOperand.getAbsolute() - LeftOperand.getAbsolute();
-
- // A - (-B) == A + B.
- if (RightOperand.isNegative())
- return LeftOperand + RightOperand.getAbsolute();
-
- // Both values are positive at this point.
- uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
- uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
- if (LeftValue >= RightValue)
- return ExpressionValue(LeftValue - RightValue);
- else {
- uint64_t AbsoluteDifference = RightValue - LeftValue;
- uint64_t MaxInt64 = std::numeric_limits<int64_t>::max();
- // Value might underflow.
- if (AbsoluteDifference > MaxInt64) {
- AbsoluteDifference -= MaxInt64;
- int64_t Result = -MaxInt64;
- int64_t MinInt64 = std::numeric_limits<int64_t>::min();
- // Underflow, tested by:
- // abs(Result + (max int64_t)) > abs((min int64_t) + (max int64_t))
- if (AbsoluteDifference > static_cast<uint64_t>(-(MinInt64 - Result)))
- return make_error<OverflowError>();
- Result -= static_cast<int64_t>(AbsoluteDifference);
- return ExpressionValue(Result);
- }
+ bool Overflow;
+ APInt Result = LeftOperand.getAPIntValue().ssub_ov(
+ RightOperand.getAPIntValue(), Overflow);
+ if (Overflow ||
+ (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1)))
+ return make_error<OverflowError>();
- return ExpressionValue(-static_cast<int64_t>(AbsoluteDifference));
- }
+ if (Result.isNegative())
+ return ExpressionValue(Result.getSExtValue());
+ else
+ return ExpressionValue(Result.getZExtValue());
}
Expected<ExpressionValue> llvm::operator*(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand) {
- // -A * -B == A * B
- if (LeftOperand.isNegative() && RightOperand.isNegative())
- return LeftOperand.getAbsolute() * RightOperand.getAbsolute();
-
- // A * -B == -B * A
- if (RightOperand.isNegative())
- return RightOperand * LeftOperand;
-
- assert(!RightOperand.isNegative() && "Unexpected negative operand!");
-
- // Result will be negative and can underflow.
- if (LeftOperand.isNegative()) {
- auto Result = LeftOperand.getAbsolute() * RightOperand.getAbsolute();
- if (!Result)
- return Result;
-
- return ExpressionValue(0) - *Result;
- }
-
- // Result will be positive and can overflow.
- uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
- uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
- std::optional<uint64_t> Result =
- checkedMulUnsigned<uint64_t>(LeftValue, RightValue);
- if (!Result)
+ bool Overflow;
+ APInt Result = LeftOperand.getAPIntValue().smul_ov(
+ RightOperand.getAPIntValue(), Overflow);
+ if (Overflow ||
+ (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1)))
return make_error<OverflowError>();
- return ExpressionValue(*Result);
+ if (Result.isNegative())
+ return ExpressionValue(Result.getSExtValue());
+ else
+ return ExpressionValue(Result.getZExtValue());
}
Expected<ExpressionValue> llvm::operator/(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand) {
- // -A / -B == A / B
- if (LeftOperand.isNegative() && RightOperand.isNegative())
- return LeftOperand.getAbsolute() / RightOperand.getAbsolute();
-
- // Check for divide by zero.
- if (RightOperand == ExpressionValue(0))
+ // Check for division by zero.
+ if (RightOperand.getAPIntValue().isZero())
return make_error<OverflowError>();
- // Result will be negative and can underflow.
- if (LeftOperand.isNegative() || RightOperand.isNegative())
- return ExpressionValue(0) -
- cantFail(LeftOperand.getAbsolute() / RightOperand.getAbsolute());
+ bool Overflow;
+ APInt Result = LeftOperand.getAPIntValue().sdiv_ov(
+ RightOperand.getAPIntValue(), Overflow);
+ if (Overflow ||
+ (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1)))
+ return make_error<OverflowError>();
- uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
- uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
- return ExpressionValue(LeftValue / RightValue);
+ if (Result.isNegative())
+ return ExpressionValue(Result.getSExtValue());
+ else
+ return ExpressionValue(Result.getZExtValue());
}
Expected<ExpressionValue> llvm::max(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand) {
- if (LeftOperand.isNegative() && RightOperand.isNegative()) {
- int64_t LeftValue = cantFail(LeftOperand.getSignedValue());
- int64_t RightValue = cantFail(RightOperand.getSignedValue());
- return ExpressionValue(std::max(LeftValue, RightValue));
- }
-
- if (!LeftOperand.isNegative() && !RightOperand.isNegative()) {
- uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
- uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
- return ExpressionValue(std::max(LeftValue, RightValue));
- }
-
- if (LeftOperand.isNegative())
- return RightOperand;
-
- return LeftOperand;
+ return LeftOperand.getAPIntValue().slt(RightOperand.getAPIntValue())
+ ? RightOperand
+ : LeftOperand;
}
Expected<ExpressionValue> llvm::min(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand) {
- if (cantFail(max(LeftOperand, RightOperand)) == LeftOperand)
+ if (cantFail(max(LeftOperand, RightOperand)).getAPIntValue() ==
+ LeftOperand.getAPIntValue())
return RightOperand;
return LeftOperand;