Index: clang/lib/Lex/LiteralSupport.cpp =================================================================== --- clang/lib/Lex/LiteralSupport.cpp +++ clang/lib/Lex/LiteralSupport.cpp @@ -1051,7 +1051,10 @@ 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) { Index: llvm/include/llvm/ADT/APFloat.h =================================================================== --- llvm/include/llvm/ADT/APFloat.h +++ llvm/include/llvm/ADT/APFloat.h @@ -38,6 +38,7 @@ class APFloat; class raw_ostream; +template class Expected; template class SmallVectorImpl; /// Enum that represents what fraction of the LSB truncated bits of an fp number @@ -299,7 +300,7 @@ bool, roundingMode); opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int, bool, roundingMode); - opStatus convertFromString(StringRef, roundingMode); + Expected convertFromString(StringRef, roundingMode); APInt bitcastToAPInt() const; double convertToDouble() const; float convertToFloat() const; @@ -525,8 +526,8 @@ bool *) const; opStatus convertFromUnsignedParts(const integerPart *, unsigned int, roundingMode); - opStatus convertFromHexadecimalString(StringRef, roundingMode); - opStatus convertFromDecimalString(StringRef, roundingMode); + Expected convertFromHexadecimalString(StringRef, roundingMode); + Expected convertFromDecimalString(StringRef, roundingMode); char *convertNormalToHexString(char *, unsigned int, bool, roundingMode) const; opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int, @@ -648,7 +649,7 @@ cmpResult compare(const DoubleAPFloat &RHS) const; bool bitwiseIsEqual(const DoubleAPFloat &RHS) const; APInt bitcastToAPInt() const; - opStatus convertFromString(StringRef, roundingMode); + Expected convertFromString(StringRef, roundingMode); opStatus next(bool nextDown); opStatus convertToInteger(MutableArrayRef Input, @@ -1105,7 +1106,7 @@ APFLOAT_DISPATCH_ON_SEMANTICS( convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM)); } - opStatus convertFromString(StringRef, roundingMode); + Expected convertFromString(StringRef, roundingMode); APInt bitcastToAPInt() const { APFLOAT_DISPATCH_ON_SEMANTICS(bitcastToAPInt()); } Index: llvm/lib/MC/MCParser/AsmParser.cpp =================================================================== --- llvm/lib/MC/MCParser/AsmParser.cpp +++ llvm/lib/MC/MCParser/AsmParser.cpp @@ -3138,8 +3138,7 @@ 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(); Index: llvm/lib/Support/APFloat.cpp =================================================================== --- llvm/lib/Support/APFloat.cpp +++ llvm/lib/Support/APFloat.cpp @@ -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 @@ -208,6 +208,10 @@ /* A bunch of private, handy routines. */ +static inline Error createError(const Twine &Err) { + return make_error(Err, inconvertibleErrorCode()); +} + static inline unsigned int partCountForBits(unsigned int bits) { @@ -226,9 +230,8 @@ If the exponent overflows, returns a large exponent with the appropriate sign. */ -static int -readExponent(StringRef::iterator begin, StringRef::iterator end) -{ +static Expected readExponent(StringRef::iterator begin, + StringRef::iterator end) { bool isNegative; unsigned int absExponent; const unsigned int overlargeExponent = 24000; /* FIXME. */ @@ -242,29 +245,28 @@ 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 @@ /* 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 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 @@ 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 @@ return exponent; } -static StringRef::iterator +static Expected 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ } 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 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 @@ 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); @@ -2302,7 +2316,7 @@ return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode); } -IEEEFloat::opStatus +Expected IEEEFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode) { lostFraction lost_fraction = lfExactlyZero; @@ -2320,14 +2334,18 @@ 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; } @@ -2344,16 +2362,23 @@ 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) { @@ -2376,7 +2401,10 @@ 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); @@ -2467,14 +2495,15 @@ } } -IEEEFloat::opStatus +Expected 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 @@ -2557,7 +2586,10 @@ } } 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 @@ -2608,9 +2640,10 @@ return false; } -IEEEFloat::opStatus IEEEFloat::convertFromString(StringRef str, - roundingMode rounding_mode) { - assert(!str.empty() && "Invalid string length"); +Expected +IEEEFloat::convertFromString(StringRef str, roundingMode rounding_mode) { + if (str.empty()) + return createError("Invalid string length"); // Handle special cases. if (convertFromStringSpecials(str)) @@ -2623,11 +2656,13 @@ 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); } @@ -4315,8 +4350,8 @@ return APInt(128, 2, Data); } -APFloat::opStatus DoubleAPFloat::convertFromString(StringRef S, - roundingMode RM) { +Expected DoubleAPFloat::convertFromString(StringRef S, + roundingMode RM) { assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); APFloat Tmp(semPPCDoubleDoubleLegacy); auto Ret = Tmp.convertFromString(S, RM); @@ -4463,7 +4498,8 @@ llvm_unreachable("Unexpected semantics"); } -APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) { +Expected APFloat::convertFromString(StringRef Str, + roundingMode RM) { APFLOAT_DISPATCH_ON_SEMANTICS(convertFromString(Str, RM)); } @@ -4477,7 +4513,8 @@ 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, Index: llvm/lib/Support/StringRef.cpp =================================================================== --- llvm/lib/Support/StringRef.cpp +++ llvm/lib/Support/StringRef.cpp @@ -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 using namespace llvm; @@ -582,8 +583,13 @@ 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; Index: llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1221,8 +1221,9 @@ // 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 @@ } 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 @@ 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. Index: llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -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" @@ -2362,7 +2362,7 @@ 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) Index: llvm/unittests/ADT/APFloatTest.cpp =================================================================== --- llvm/unittests/ADT/APFloatTest.cpp +++ llvm/unittests/ADT/APFloatTest.cpp @@ -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 #include @@ -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(); } @@ -1147,172 +1155,172 @@ EXPECT_DEATH(APFloat(APFloat::IEEEsingle(), 0.0f).convertToDouble(), "Float semantics are not IEEEdouble"); EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), 0.0 ).convertToFloat(), "Float semantics are not IEEEsingle"); } +#endif +#endif -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"); +TEST(APFloatTest, StringDecimalError) { + EXPECT_EQ("Invalid string length", convertToErrorFromString("")); + EXPECT_EQ("String has no digits", convertToErrorFromString("+")); + EXPECT_EQ("String has no digits", convertToErrorFromString("-")); - 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_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_DEATH(APFloat(APFloat::IEEEdouble(), "1.0f"), "Invalid character in significand"); + EXPECT_EQ("Invalid character in significand", convertToErrorFromString("1.0f")); - 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"); + 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, 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"); +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_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_EQ("Significand has no digits", convertToErrorFromString( "e")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("+e")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("-e")); - 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_EQ("Significand has no digits", convertToErrorFromString( "e1")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("+e1")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("-e1")); - 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_EQ("Significand has no digits", convertToErrorFromString( ".e1")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("+.e1")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("-.e1")); - 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_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, 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"); +TEST(APFloatTest, StringHexadecimalError) { + EXPECT_EQ("Invalid string", convertToErrorFromString( "0x")); + EXPECT_EQ("Invalid string", convertToErrorFromString("+0x")); + EXPECT_EQ("Invalid string", convertToErrorFromString("-0x")); - 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_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_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_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_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_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_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_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_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_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_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p0f"), "Invalid character in exponent"); + EXPECT_EQ("Invalid character in exponent", convertToErrorFromString("0x1p0f")); - 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"); + 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, 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"); +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_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_EQ("Significand has no digits", convertToErrorFromString( "0xp")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0xp")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0xp")); - 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_EQ("Significand has no digits", convertToErrorFromString( "0xp+")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0xp+")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0xp+")); - 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_EQ("Significand has no digits", convertToErrorFromString( "0xp-")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0xp-")); + EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0xp-")); - 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_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_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_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_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_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, 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"); +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_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_EQ("Exponent has no digits", convertToErrorFromString( "0x1p+")); + EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1p+")); + EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1p+")); - 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_EQ("Exponent has no digits", convertToErrorFromString( "0x1p-")); + EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1p-")); + EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1p-")); - 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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-")); } -#endif -#endif TEST(APFloatTest, exactInverse) { APFloat inv(0.0f);