forked from OSchip/llvm-project
[APFloat] Add recoverable string parsing errors to APFloat
Implementing the APFloat part in PR4745. Differential Revision: https://reviews.llvm.org/D69770
This commit is contained in:
parent
a792953330
commit
c5fb73c5d1
|
@ -1051,7 +1051,10 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) {
|
|||
Str = Buffer;
|
||||
}
|
||||
|
||||
return Result.convertFromString(Str, APFloat::rmNearestTiesToEven);
|
||||
auto StatusOrErr =
|
||||
Result.convertFromString(Str, APFloat::rmNearestTiesToEven);
|
||||
assert(StatusOrErr && "Invalid floating point representation");
|
||||
return StatusOrErr ? *StatusOrErr : APFloat::opInvalidOp;
|
||||
}
|
||||
|
||||
static inline bool IsExponentPart(char c) {
|
||||
|
|
|
@ -38,6 +38,7 @@ class StringRef;
|
|||
class APFloat;
|
||||
class raw_ostream;
|
||||
|
||||
template <typename T> class Expected;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
|
||||
/// Enum that represents what fraction of the LSB truncated bits of an fp number
|
||||
|
@ -299,7 +300,7 @@ public:
|
|||
bool, roundingMode);
|
||||
opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
|
||||
bool, roundingMode);
|
||||
opStatus convertFromString(StringRef, roundingMode);
|
||||
Expected<opStatus> convertFromString(StringRef, roundingMode);
|
||||
APInt bitcastToAPInt() const;
|
||||
double convertToDouble() const;
|
||||
float convertToFloat() const;
|
||||
|
@ -525,8 +526,8 @@ private:
|
|||
bool *) const;
|
||||
opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
|
||||
roundingMode);
|
||||
opStatus convertFromHexadecimalString(StringRef, roundingMode);
|
||||
opStatus convertFromDecimalString(StringRef, roundingMode);
|
||||
Expected<opStatus> convertFromHexadecimalString(StringRef, roundingMode);
|
||||
Expected<opStatus> convertFromDecimalString(StringRef, roundingMode);
|
||||
char *convertNormalToHexString(char *, unsigned int, bool,
|
||||
roundingMode) const;
|
||||
opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int,
|
||||
|
@ -648,7 +649,7 @@ public:
|
|||
cmpResult compare(const DoubleAPFloat &RHS) const;
|
||||
bool bitwiseIsEqual(const DoubleAPFloat &RHS) const;
|
||||
APInt bitcastToAPInt() const;
|
||||
opStatus convertFromString(StringRef, roundingMode);
|
||||
Expected<opStatus> convertFromString(StringRef, roundingMode);
|
||||
opStatus next(bool nextDown);
|
||||
|
||||
opStatus convertToInteger(MutableArrayRef<integerPart> Input,
|
||||
|
@ -1108,7 +1109,7 @@ public:
|
|||
APFLOAT_DISPATCH_ON_SEMANTICS(
|
||||
convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM));
|
||||
}
|
||||
opStatus convertFromString(StringRef, roundingMode);
|
||||
Expected<opStatus> convertFromString(StringRef, roundingMode);
|
||||
APInt bitcastToAPInt() const {
|
||||
APFLOAT_DISPATCH_ON_SEMANTICS(bitcastToAPInt());
|
||||
}
|
||||
|
|
|
@ -3130,8 +3130,7 @@ bool AsmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
|
|||
Value = APFloat::getNaN(Semantics, false, ~0);
|
||||
else
|
||||
return TokError("invalid floating point literal");
|
||||
} else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
|
||||
APFloat::opInvalidOp)
|
||||
} else if (!Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven))
|
||||
return TokError("invalid floating point literal");
|
||||
if (IsNeg)
|
||||
Value.changeSign();
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstring>
|
||||
|
@ -208,6 +208,10 @@ namespace llvm {
|
|||
|
||||
/* A bunch of private, handy routines. */
|
||||
|
||||
static inline Error createError(const Twine &Err) {
|
||||
return make_error<StringError>(Err, inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
partCountForBits(unsigned int bits)
|
||||
{
|
||||
|
@ -226,9 +230,8 @@ decDigitValue(unsigned int c)
|
|||
|
||||
If the exponent overflows, returns a large exponent with the
|
||||
appropriate sign. */
|
||||
static int
|
||||
readExponent(StringRef::iterator begin, StringRef::iterator end)
|
||||
{
|
||||
static Expected<int> readExponent(StringRef::iterator begin,
|
||||
StringRef::iterator end) {
|
||||
bool isNegative;
|
||||
unsigned int absExponent;
|
||||
const unsigned int overlargeExponent = 24000; /* FIXME. */
|
||||
|
@ -242,29 +245,28 @@ readExponent(StringRef::iterator begin, StringRef::iterator end)
|
|||
isNegative = (*p == '-');
|
||||
if (*p == '-' || *p == '+') {
|
||||
p++;
|
||||
assert(p != end && "Exponent has no digits");
|
||||
if (p == end)
|
||||
return createError("Exponent has no digits");
|
||||
}
|
||||
|
||||
absExponent = decDigitValue(*p++);
|
||||
assert(absExponent < 10U && "Invalid character in exponent");
|
||||
if (absExponent >= 10U)
|
||||
return createError("Invalid character in exponent");
|
||||
|
||||
for (; p != end; ++p) {
|
||||
unsigned int value;
|
||||
|
||||
value = decDigitValue(*p);
|
||||
assert(value < 10U && "Invalid character in exponent");
|
||||
if (value >= 10U)
|
||||
return createError("Invalid character in exponent");
|
||||
|
||||
value += absExponent * 10;
|
||||
absExponent = absExponent * 10U + value;
|
||||
if (absExponent >= overlargeExponent) {
|
||||
absExponent = overlargeExponent;
|
||||
p = end; /* outwit assert below */
|
||||
break;
|
||||
}
|
||||
absExponent = value;
|
||||
}
|
||||
|
||||
assert(p == end && "Invalid exponent in exponent");
|
||||
|
||||
if (isNegative)
|
||||
return -(int) absExponent;
|
||||
else
|
||||
|
@ -273,20 +275,21 @@ readExponent(StringRef::iterator begin, StringRef::iterator end)
|
|||
|
||||
/* This is ugly and needs cleaning up, but I don't immediately see
|
||||
how whilst remaining safe. */
|
||||
static int
|
||||
totalExponent(StringRef::iterator p, StringRef::iterator end,
|
||||
int exponentAdjustment)
|
||||
{
|
||||
static Expected<int> totalExponent(StringRef::iterator p,
|
||||
StringRef::iterator end,
|
||||
int exponentAdjustment) {
|
||||
int unsignedExponent;
|
||||
bool negative, overflow;
|
||||
int exponent = 0;
|
||||
|
||||
assert(p != end && "Exponent has no digits");
|
||||
if (p == end)
|
||||
return createError("Exponent has no digits");
|
||||
|
||||
negative = *p == '-';
|
||||
if (*p == '-' || *p == '+') {
|
||||
p++;
|
||||
assert(p != end && "Exponent has no digits");
|
||||
if (p == end)
|
||||
return createError("Exponent has no digits");
|
||||
}
|
||||
|
||||
unsignedExponent = 0;
|
||||
|
@ -295,7 +298,8 @@ totalExponent(StringRef::iterator p, StringRef::iterator end,
|
|||
unsigned int value;
|
||||
|
||||
value = decDigitValue(*p);
|
||||
assert(value < 10U && "Invalid character in exponent");
|
||||
if (value >= 10U)
|
||||
return createError("Invalid character in exponent");
|
||||
|
||||
unsignedExponent = unsignedExponent * 10 + value;
|
||||
if (unsignedExponent > 32767) {
|
||||
|
@ -322,10 +326,9 @@ totalExponent(StringRef::iterator p, StringRef::iterator end,
|
|||
return exponent;
|
||||
}
|
||||
|
||||
static StringRef::iterator
|
||||
static Expected<StringRef::iterator>
|
||||
skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end,
|
||||
StringRef::iterator *dot)
|
||||
{
|
||||
StringRef::iterator *dot) {
|
||||
StringRef::iterator p = begin;
|
||||
*dot = end;
|
||||
while (p != end && *p == '0')
|
||||
|
@ -334,7 +337,8 @@ skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end,
|
|||
if (p != end && *p == '.') {
|
||||
*dot = p++;
|
||||
|
||||
assert(end - begin != 1 && "Significand has no digits");
|
||||
if (end - begin == 1)
|
||||
return createError("Significand has no digits");
|
||||
|
||||
while (p != end && *p == '0')
|
||||
p++;
|
||||
|
@ -363,12 +367,14 @@ struct decimalInfo {
|
|||
int normalizedExponent;
|
||||
};
|
||||
|
||||
static void
|
||||
interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
|
||||
decimalInfo *D)
|
||||
{
|
||||
static Error interpretDecimal(StringRef::iterator begin,
|
||||
StringRef::iterator end, decimalInfo *D) {
|
||||
StringRef::iterator dot = end;
|
||||
StringRef::iterator p = skipLeadingZeroesAndAnyDot (begin, end, &dot);
|
||||
|
||||
auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot);
|
||||
if (!PtrOrErr)
|
||||
return PtrOrErr.takeError();
|
||||
StringRef::iterator p = *PtrOrErr;
|
||||
|
||||
D->firstSigDigit = p;
|
||||
D->exponent = 0;
|
||||
|
@ -376,7 +382,8 @@ interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
|
|||
|
||||
for (; p != end; ++p) {
|
||||
if (*p == '.') {
|
||||
assert(dot == end && "String contains multiple dots");
|
||||
if (dot != end)
|
||||
return createError("String contains multiple dots");
|
||||
dot = p++;
|
||||
if (p == end)
|
||||
break;
|
||||
|
@ -386,12 +393,18 @@ interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
|
|||
}
|
||||
|
||||
if (p != end) {
|
||||
assert((*p == 'e' || *p == 'E') && "Invalid character in significand");
|
||||
assert(p != begin && "Significand has no digits");
|
||||
assert((dot == end || p - begin != 1) && "Significand has no digits");
|
||||
if (*p != 'e' && *p != 'E')
|
||||
return createError("Invalid character in significand");
|
||||
if (p == begin)
|
||||
return createError("Significand has no digits");
|
||||
if (dot != end && p - begin == 1)
|
||||
return createError("Significand has no digits");
|
||||
|
||||
/* p points to the first non-digit in the string */
|
||||
D->exponent = readExponent(p + 1, end);
|
||||
auto ExpOrErr = readExponent(p + 1, end);
|
||||
if (!ExpOrErr)
|
||||
return ExpOrErr.takeError();
|
||||
D->exponent = *ExpOrErr;
|
||||
|
||||
/* Implied decimal point? */
|
||||
if (dot == end)
|
||||
|
@ -417,15 +430,15 @@ interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
|
|||
}
|
||||
|
||||
D->lastSigDigit = p;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
/* Return the trailing fraction of a hexadecimal number.
|
||||
DIGITVALUE is the first hex digit of the fraction, P points to
|
||||
the next digit. */
|
||||
static lostFraction
|
||||
static Expected<lostFraction>
|
||||
trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
|
||||
unsigned int digitValue)
|
||||
{
|
||||
unsigned int digitValue) {
|
||||
unsigned int hexDigit;
|
||||
|
||||
/* If the first trailing digit isn't 0 or 8 we can work out the
|
||||
|
@ -439,7 +452,8 @@ trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
|
|||
while (p != end && (*p == '0' || *p == '.'))
|
||||
p++;
|
||||
|
||||
assert(p != end && "Invalid trailing hexadecimal fraction!");
|
||||
if (p == end)
|
||||
return createError("Invalid trailing hexadecimal fraction!");
|
||||
|
||||
hexDigit = hexDigitValue(*p);
|
||||
|
||||
|
@ -2299,7 +2313,7 @@ IEEEFloat::convertFromZeroExtendedInteger(const integerPart *parts,
|
|||
return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
|
||||
}
|
||||
|
||||
IEEEFloat::opStatus
|
||||
Expected<IEEEFloat::opStatus>
|
||||
IEEEFloat::convertFromHexadecimalString(StringRef s,
|
||||
roundingMode rounding_mode) {
|
||||
lostFraction lost_fraction = lfExactlyZero;
|
||||
|
@ -2317,14 +2331,18 @@ IEEEFloat::convertFromHexadecimalString(StringRef s,
|
|||
StringRef::iterator begin = s.begin();
|
||||
StringRef::iterator end = s.end();
|
||||
StringRef::iterator dot;
|
||||
StringRef::iterator p = skipLeadingZeroesAndAnyDot(begin, end, &dot);
|
||||
auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot);
|
||||
if (!PtrOrErr)
|
||||
return PtrOrErr.takeError();
|
||||
StringRef::iterator p = *PtrOrErr;
|
||||
StringRef::iterator firstSignificantDigit = p;
|
||||
|
||||
while (p != end) {
|
||||
integerPart hex_value;
|
||||
|
||||
if (*p == '.') {
|
||||
assert(dot == end && "String contains multiple dots");
|
||||
if (dot != end)
|
||||
return createError("String contains multiple dots");
|
||||
dot = p++;
|
||||
continue;
|
||||
}
|
||||
|
@ -2341,16 +2359,23 @@ IEEEFloat::convertFromHexadecimalString(StringRef s,
|
|||
hex_value <<= bitPos % integerPartWidth;
|
||||
significand[bitPos / integerPartWidth] |= hex_value;
|
||||
} else if (!computedTrailingFraction) {
|
||||
lost_fraction = trailingHexadecimalFraction(p, end, hex_value);
|
||||
auto FractOrErr = trailingHexadecimalFraction(p, end, hex_value);
|
||||
if (!FractOrErr)
|
||||
return FractOrErr.takeError();
|
||||
lost_fraction = *FractOrErr;
|
||||
computedTrailingFraction = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hex floats require an exponent but not a hexadecimal point. */
|
||||
assert(p != end && "Hex strings require an exponent");
|
||||
assert((*p == 'p' || *p == 'P') && "Invalid character in significand");
|
||||
assert(p != begin && "Significand has no digits");
|
||||
assert((dot == end || p - begin != 1) && "Significand has no digits");
|
||||
if (p == end)
|
||||
return createError("Hex strings require an exponent");
|
||||
if (*p != 'p' && *p != 'P')
|
||||
return createError("Invalid character in significand");
|
||||
if (p == begin)
|
||||
return createError("Significand has no digits");
|
||||
if (dot != end && p - begin == 1)
|
||||
return createError("Significand has no digits");
|
||||
|
||||
/* Ignore the exponent if we are zero. */
|
||||
if (p != firstSignificantDigit) {
|
||||
|
@ -2373,7 +2398,10 @@ IEEEFloat::convertFromHexadecimalString(StringRef s,
|
|||
expAdjustment -= partsCount * integerPartWidth;
|
||||
|
||||
/* Adjust for the given exponent. */
|
||||
exponent = totalExponent(p + 1, end, expAdjustment);
|
||||
auto ExpOrErr = totalExponent(p + 1, end, expAdjustment);
|
||||
if (!ExpOrErr)
|
||||
return ExpOrErr.takeError();
|
||||
exponent = *ExpOrErr;
|
||||
}
|
||||
|
||||
return normalize(rounding_mode, lost_fraction);
|
||||
|
@ -2464,14 +2492,15 @@ IEEEFloat::roundSignificandWithExponent(const integerPart *decSigParts,
|
|||
}
|
||||
}
|
||||
|
||||
IEEEFloat::opStatus
|
||||
Expected<IEEEFloat::opStatus>
|
||||
IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) {
|
||||
decimalInfo D;
|
||||
opStatus fs;
|
||||
|
||||
/* Scan the text. */
|
||||
StringRef::iterator p = str.begin();
|
||||
interpretDecimal(p, str.end(), &D);
|
||||
if (Error Err = interpretDecimal(p, str.end(), &D))
|
||||
return std::move(Err);
|
||||
|
||||
/* Handle the quick cases. First the case of no significant digits,
|
||||
i.e. zero, and then exponents that are obviously too large or too
|
||||
|
@ -2554,7 +2583,10 @@ IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) {
|
|||
}
|
||||
}
|
||||
decValue = decDigitValue(*p++);
|
||||
assert(decValue < 10U && "Invalid character in significand");
|
||||
if (decValue >= 10U) {
|
||||
delete[] decSignificand;
|
||||
return createError("Invalid character in significand");
|
||||
}
|
||||
multiplier *= 10;
|
||||
val = val * 10 + decValue;
|
||||
/* The maximum number that can be multiplied by ten with any
|
||||
|
@ -2605,9 +2637,10 @@ bool IEEEFloat::convertFromStringSpecials(StringRef str) {
|
|||
return false;
|
||||
}
|
||||
|
||||
IEEEFloat::opStatus IEEEFloat::convertFromString(StringRef str,
|
||||
roundingMode rounding_mode) {
|
||||
assert(!str.empty() && "Invalid string length");
|
||||
Expected<IEEEFloat::opStatus>
|
||||
IEEEFloat::convertFromString(StringRef str, roundingMode rounding_mode) {
|
||||
if (str.empty())
|
||||
return createError("Invalid string length");
|
||||
|
||||
// Handle special cases.
|
||||
if (convertFromStringSpecials(str))
|
||||
|
@ -2620,11 +2653,13 @@ IEEEFloat::opStatus IEEEFloat::convertFromString(StringRef str,
|
|||
if (*p == '-' || *p == '+') {
|
||||
p++;
|
||||
slen--;
|
||||
assert(slen && "String has no digits");
|
||||
if (!slen)
|
||||
return createError("String has no digits");
|
||||
}
|
||||
|
||||
if (slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
|
||||
assert(slen - 2 && "Invalid string");
|
||||
if (slen == 2)
|
||||
return createError("Invalid string");
|
||||
return convertFromHexadecimalString(StringRef(p + 2, slen - 2),
|
||||
rounding_mode);
|
||||
}
|
||||
|
@ -4312,8 +4347,8 @@ APInt DoubleAPFloat::bitcastToAPInt() const {
|
|||
return APInt(128, 2, Data);
|
||||
}
|
||||
|
||||
APFloat::opStatus DoubleAPFloat::convertFromString(StringRef S,
|
||||
roundingMode RM) {
|
||||
Expected<APFloat::opStatus> DoubleAPFloat::convertFromString(StringRef S,
|
||||
roundingMode RM) {
|
||||
assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
|
||||
APFloat Tmp(semPPCDoubleDoubleLegacy);
|
||||
auto Ret = Tmp.convertFromString(S, RM);
|
||||
|
@ -4460,7 +4495,8 @@ APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) {
|
|||
llvm_unreachable("Unexpected semantics");
|
||||
}
|
||||
|
||||
APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) {
|
||||
Expected<APFloat::opStatus> APFloat::convertFromString(StringRef Str,
|
||||
roundingMode RM) {
|
||||
APFLOAT_DISPATCH_ON_SEMANTICS(convertFromString(Str, RM));
|
||||
}
|
||||
|
||||
|
@ -4474,7 +4510,8 @@ hash_code hash_value(const APFloat &Arg) {
|
|||
|
||||
APFloat::APFloat(const fltSemantics &Semantics, StringRef S)
|
||||
: APFloat(Semantics) {
|
||||
convertFromString(S, rmNearestTiesToEven);
|
||||
auto StatusOrErr = convertFromString(S, rmNearestTiesToEven);
|
||||
assert(StatusOrErr && "Invalid floating point representation");
|
||||
}
|
||||
|
||||
APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/edit_distance.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <bitset>
|
||||
|
||||
using namespace llvm;
|
||||
|
@ -587,8 +588,13 @@ bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
|
|||
|
||||
bool StringRef::getAsDouble(double &Result, bool AllowInexact) const {
|
||||
APFloat F(0.0);
|
||||
APFloat::opStatus Status =
|
||||
F.convertFromString(*this, APFloat::rmNearestTiesToEven);
|
||||
auto ErrOrStatus = F.convertFromString(*this, APFloat::rmNearestTiesToEven);
|
||||
if (!ErrOrStatus) {
|
||||
assert("Invalid floating point representation");
|
||||
return true;
|
||||
}
|
||||
|
||||
APFloat::opStatus Status = *ErrOrStatus;
|
||||
if (Status != APFloat::opOK) {
|
||||
if (!AllowInexact || !(Status & APFloat::opInexact))
|
||||
return true;
|
||||
|
|
|
@ -1221,8 +1221,9 @@ public:
|
|||
|
||||
// Calculate its FP value.
|
||||
APFloat RealVal(APFloat::IEEEdouble());
|
||||
if (RealVal.convertFromString(Desc->Repr, APFloat::rmTowardZero) !=
|
||||
APFloat::opOK)
|
||||
auto StatusOrErr =
|
||||
RealVal.convertFromString(Desc->Repr, APFloat::rmTowardZero);
|
||||
if (!StatusOrErr || *StatusOrErr != APFloat::opOK)
|
||||
llvm_unreachable("FP immediate is not exact");
|
||||
|
||||
if (getFPImm().bitwiseIsEqual(RealVal))
|
||||
|
@ -2577,8 +2578,13 @@ AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
|
|||
} else {
|
||||
// Parse FP representation.
|
||||
APFloat RealVal(APFloat::IEEEdouble());
|
||||
auto Status =
|
||||
auto StatusOrErr =
|
||||
RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero);
|
||||
if (!StatusOrErr) {
|
||||
TokError("invalid floating point representation");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
if (isNegative)
|
||||
RealVal.changeSign();
|
||||
|
||||
|
@ -2589,7 +2595,7 @@ AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
|
|||
AArch64Operand::CreateToken(".0", false, S, getContext()));
|
||||
} else
|
||||
Operands.push_back(AArch64Operand::CreateFPImm(
|
||||
RealVal, Status == APFloat::opOK, S, getContext()));
|
||||
RealVal, *StatusOrErr == APFloat::opOK, S, getContext()));
|
||||
}
|
||||
|
||||
Parser.Lex(); // Eat the token.
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "llvm/Support/AMDHSAKernelDescriptor.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/MachineValueType.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/SMLoc.h"
|
||||
|
@ -2363,7 +2363,7 @@ AMDGPUAsmParser::parseImm(OperandVector &Operands, bool HasSP3AbsModifier) {
|
|||
|
||||
APFloat RealVal(APFloat::IEEEdouble());
|
||||
auto roundMode = APFloat::rmNearestTiesToEven;
|
||||
if (RealVal.convertFromString(Num, roundMode) == APFloat::opInvalidOp) {
|
||||
if (!RealVal.convertFromString(Num, roundMode)) {
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
if (Negate)
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <cmath>
|
||||
#include <ostream>
|
||||
|
@ -20,9 +20,17 @@
|
|||
|
||||
using namespace llvm;
|
||||
|
||||
static double convertToDoubleFromString(const char *Str) {
|
||||
static std::string convertToErrorFromString(StringRef Str) {
|
||||
llvm::APFloat F(0.0);
|
||||
F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven);
|
||||
auto ErrOrStatus =
|
||||
F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven);
|
||||
EXPECT_TRUE(!ErrOrStatus);
|
||||
return toString(ErrOrStatus.takeError());
|
||||
}
|
||||
|
||||
static double convertToDoubleFromString(StringRef Str) {
|
||||
llvm::APFloat F(0.0);
|
||||
EXPECT_FALSE(!F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven));
|
||||
return F.convertToDouble();
|
||||
}
|
||||
|
||||
|
@ -1156,173 +1164,173 @@ TEST(APFloatTest, SemanticsDeath) {
|
|||
EXPECT_DEATH(APFloat(APFloat::IEEEsingle(), 0).convertToDouble(), "Float semantics are not IEEEdouble");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), 0).convertToFloat(), "Float semantics are not IEEEsingle");
|
||||
}
|
||||
|
||||
TEST(APFloatTest, StringDecimalDeath) {
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ""), "Invalid string length");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+"), "String has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-"), "String has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("\0", 1)), "Invalid character in significand");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1\0", 2)), "Invalid character in significand");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1" "\0" "2", 3)), "Invalid character in significand");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1" "\0" "2e1", 5)), "Invalid character in significand");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e\0", 3)), "Invalid character in exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e1\0", 4)), "Invalid character in exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e1" "\0" "2", 5)), "Invalid character in exponent");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0f"), "Invalid character in significand");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".."), "String contains multiple dots");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "..0"), "String contains multiple dots");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0.0"), "String contains multiple dots");
|
||||
}
|
||||
|
||||
TEST(APFloatTest, StringDecimalSignificandDeath) {
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "."), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+."), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-."), "Significand has no digits");
|
||||
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "e"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+e"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-e"), "Significand has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "e1"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+e1"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-e1"), "Significand has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".e1"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.e1"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e1"), "Significand has no digits");
|
||||
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".e"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.e"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e"), "Significand has no digits");
|
||||
}
|
||||
|
||||
TEST(APFloatTest, StringHexadecimalDeath) {
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x"), "Invalid string");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x"), "Invalid string");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x"), "Invalid string");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0"), "Hex strings require an exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0"), "Hex strings require an exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0"), "Hex strings require an exponent");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0."), "Hex strings require an exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0."), "Hex strings require an exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0."), "Hex strings require an exponent");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.0"), "Hex strings require an exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.0"), "Hex strings require an exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.0"), "Hex strings require an exponent");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0.0"), "Hex strings require an exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0.0"), "Hex strings require an exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0.0"), "Hex strings require an exponent");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x\0", 3)), "Invalid character in significand");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1\0", 4)), "Invalid character in significand");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1" "\0" "2", 5)), "Invalid character in significand");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1" "\0" "2p1", 7)), "Invalid character in significand");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p\0", 5)), "Invalid character in exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p1\0", 6)), "Invalid character in exponent");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p1" "\0" "2", 7)), "Invalid character in exponent");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p0f"), "Invalid character in exponent");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x..p1"), "String contains multiple dots");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x..0p1"), "String contains multiple dots");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.0.0p1"), "String contains multiple dots");
|
||||
}
|
||||
|
||||
TEST(APFloatTest, StringHexadecimalSignificandDeath) {
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x."), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x."), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x."), "Significand has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp"), "Significand has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp+"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp+"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp+"), "Significand has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp-"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp-"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp-"), "Significand has no digits");
|
||||
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p"), "Significand has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p+"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p+"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p+"), "Significand has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p-"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p-"), "Significand has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p-"), "Significand has no digits");
|
||||
}
|
||||
|
||||
TEST(APFloatTest, StringHexadecimalExponentDeath) {
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p"), "Exponent has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p+"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p+"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p+"), "Exponent has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p-"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p-"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p-"), "Exponent has no digits");
|
||||
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p"), "Exponent has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p+"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p+"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p+"), "Exponent has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p-"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p-"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p-"), "Exponent has no digits");
|
||||
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p"), "Exponent has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p+"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p+"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p+"), "Exponent has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p-"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p-"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p-"), "Exponent has no digits");
|
||||
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p"), "Exponent has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p+"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p+"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p+"), "Exponent has no digits");
|
||||
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p-"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p-"), "Exponent has no digits");
|
||||
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p-"), "Exponent has no digits");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TEST(APFloatTest, StringDecimalError) {
|
||||
EXPECT_EQ("Invalid string length", convertToErrorFromString(""));
|
||||
EXPECT_EQ("String has no digits", convertToErrorFromString("+"));
|
||||
EXPECT_EQ("String has no digits", convertToErrorFromString("-"));
|
||||
|
||||
EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("\0", 1)));
|
||||
EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("1\0", 2)));
|
||||
EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("1" "\0" "2", 3)));
|
||||
EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("1" "\0" "2e1", 5)));
|
||||
EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("1e\0", 3)));
|
||||
EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("1e1\0", 4)));
|
||||
EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("1e1" "\0" "2", 5)));
|
||||
|
||||
EXPECT_EQ("Invalid character in significand", convertToErrorFromString("1.0f"));
|
||||
|
||||
EXPECT_EQ("String contains multiple dots", convertToErrorFromString(".."));
|
||||
EXPECT_EQ("String contains multiple dots", convertToErrorFromString("..0"));
|
||||
EXPECT_EQ("String contains multiple dots", convertToErrorFromString("1.0.0"));
|
||||
}
|
||||
|
||||
TEST(APFloatTest, StringDecimalSignificandError) {
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "."));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+."));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-."));
|
||||
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "e"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+e"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-e"));
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "e1"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+e1"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-e1"));
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( ".e1"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+.e1"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-.e1"));
|
||||
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( ".e"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+.e"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-.e"));
|
||||
}
|
||||
|
||||
TEST(APFloatTest, StringHexadecimalError) {
|
||||
EXPECT_EQ("Invalid string", convertToErrorFromString( "0x"));
|
||||
EXPECT_EQ("Invalid string", convertToErrorFromString("+0x"));
|
||||
EXPECT_EQ("Invalid string", convertToErrorFromString("-0x"));
|
||||
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString( "0x0"));
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("+0x0"));
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("-0x0"));
|
||||
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString( "0x0."));
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("+0x0."));
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("-0x0."));
|
||||
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString( "0x.0"));
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("+0x.0"));
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("-0x.0"));
|
||||
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString( "0x0.0"));
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("+0x0.0"));
|
||||
EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("-0x0.0"));
|
||||
|
||||
EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("0x\0", 3)));
|
||||
EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("0x1\0", 4)));
|
||||
EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("0x1" "\0" "2", 5)));
|
||||
EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("0x1" "\0" "2p1", 7)));
|
||||
EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("0x1p\0", 5)));
|
||||
EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("0x1p1\0", 6)));
|
||||
EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("0x1p1" "\0" "2", 7)));
|
||||
|
||||
EXPECT_EQ("Invalid character in exponent", convertToErrorFromString("0x1p0f"));
|
||||
|
||||
EXPECT_EQ("String contains multiple dots", convertToErrorFromString("0x..p1"));
|
||||
EXPECT_EQ("String contains multiple dots", convertToErrorFromString("0x..0p1"));
|
||||
EXPECT_EQ("String contains multiple dots", convertToErrorFromString("0x1.0.0p1"));
|
||||
}
|
||||
|
||||
TEST(APFloatTest, StringHexadecimalSignificandError) {
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0x."));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0x."));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0x."));
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0xp"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0xp"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0xp"));
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0xp+"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0xp+"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0xp+"));
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0xp-"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0xp-"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0xp-"));
|
||||
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0x.p"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0x.p"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0x.p"));
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0x.p+"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0x.p+"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0x.p+"));
|
||||
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0x.p-"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0x.p-"));
|
||||
EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0x.p-"));
|
||||
}
|
||||
|
||||
TEST(APFloatTest, StringHexadecimalExponentError) {
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1p"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1p"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1p"));
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1p+"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1p+"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1p+"));
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1p-"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1p-"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1p-"));
|
||||
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.p"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.p"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.p"));
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.p+"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.p+"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.p+"));
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.p-"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.p-"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.p-"));
|
||||
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x.1p"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x.1p"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x.1p"));
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x.1p+"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x.1p+"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x.1p+"));
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x.1p-"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x.1p-"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x.1p-"));
|
||||
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.1p"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.1p"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.1p"));
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.1p+"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.1p+"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.1p+"));
|
||||
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.1p-"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.1p-"));
|
||||
EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.1p-"));
|
||||
}
|
||||
|
||||
TEST(APFloatTest, exactInverse) {
|
||||
APFloat inv(0.0f);
|
||||
|
||||
|
|
Loading…
Reference in New Issue