diff options
Diffstat (limited to 'llvm/lib/FileCheck/FileCheck.cpp')
-rw-r--r-- | llvm/lib/FileCheck/FileCheck.cpp | 230 |
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; |