Modify APFloat to take a StringRef instead of a c string.

This also adds unit tests to APFloat that mainly tests the
string handling of APFloat, but not much else of it's api.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79210 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Erick Tryzelaar 2009-08-16 23:36:19 +00:00
parent 1b9104ff80
commit a15d890c34
3 changed files with 217 additions and 67 deletions

View File

@ -109,6 +109,7 @@ namespace llvm {
typedef signed short exponent_t; typedef signed short exponent_t;
struct fltSemantics; struct fltSemantics;
struct StringRef;
/* When bits of a floating point number are truncated, this enum is /* When bits of a floating point number are truncated, this enum is
used to indicate what fraction of the LSB those bits represented. used to indicate what fraction of the LSB those bits represented.
@ -172,7 +173,7 @@ namespace llvm {
}; };
// Constructors. // Constructors.
APFloat(const fltSemantics &, const char *); APFloat(const fltSemantics &, const StringRef &);
APFloat(const fltSemantics &, integerPart); APFloat(const fltSemantics &, integerPart);
APFloat(const fltSemantics &, fltCategory, bool negative, unsigned type=0); APFloat(const fltSemantics &, fltCategory, bool negative, unsigned type=0);
explicit APFloat(double d); explicit APFloat(double d);
@ -234,7 +235,7 @@ namespace llvm {
bool, roundingMode); bool, roundingMode);
opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int, opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
bool, roundingMode); bool, roundingMode);
opStatus convertFromString(const char *, roundingMode); opStatus convertFromString(const StringRef&, roundingMode);
APInt bitcastToAPInt() const; APInt bitcastToAPInt() const;
double convertToDouble() const; double convertToDouble() const;
float convertToFloat() const; float convertToFloat() const;
@ -312,8 +313,8 @@ namespace llvm {
roundingMode, bool *) const; roundingMode, bool *) const;
opStatus convertFromUnsignedParts(const integerPart *, unsigned int, opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
roundingMode); roundingMode);
opStatus convertFromHexadecimalString(const char *, roundingMode); opStatus convertFromHexadecimalString(const StringRef&, roundingMode);
opStatus convertFromDecimalString (const char *, roundingMode); opStatus convertFromDecimalString (const StringRef&, roundingMode);
char *convertNormalToHexString(char *, unsigned int, bool, char *convertNormalToHexString(char *, unsigned int, bool,
roundingMode) const; roundingMode) const;
opStatus roundSignificandWithExponent(const integerPart *, unsigned int, opStatus roundSignificandWithExponent(const integerPart *, unsigned int,

View File

@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/ADT/APFloat.h" #include "llvm/ADT/APFloat.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
@ -123,27 +124,30 @@ assertArithmeticOK(const llvm::fltSemantics &semantics) {
If the exponent overflows, returns a large exponent with the If the exponent overflows, returns a large exponent with the
appropriate sign. */ appropriate sign. */
static int static int
readExponent(const char *p) readExponent(StringRef::iterator begin, StringRef::iterator end)
{ {
bool isNegative; bool isNegative;
unsigned int absExponent; unsigned int absExponent;
const unsigned int overlargeExponent = 24000; /* FIXME. */ const unsigned int overlargeExponent = 24000; /* FIXME. */
StringRef::iterator p = begin;
assert(p != end && "Exponent has no digits");
isNegative = (*p == '-'); isNegative = (*p == '-');
if (*p == '-' || *p == '+') if (*p == '-' || *p == '+') {
p++; p++;
assert(p != end && "Exponent has no digits");
}
absExponent = decDigitValue(*p++); absExponent = decDigitValue(*p++);
assert (absExponent < 10U); assert(absExponent < 10U && "Invalid character in exponent");
for (;;) { for (; p != end; ++p) {
unsigned int value; unsigned int value;
value = decDigitValue(*p); value = decDigitValue(*p);
if (value >= 10U) assert(value < 10U && "Invalid character in exponent");
break;
p++;
value += absExponent * 10; value += absExponent * 10;
if (absExponent >= overlargeExponent) { if (absExponent >= overlargeExponent) {
absExponent = overlargeExponent; absExponent = overlargeExponent;
@ -152,6 +156,8 @@ readExponent(const char *p)
absExponent = value; absExponent = value;
} }
assert(p == end && "Invalid exponent in exponent");
if (isNegative) if (isNegative)
return -(int) absExponent; return -(int) absExponent;
else else
@ -161,7 +167,8 @@ readExponent(const char *p)
/* This is ugly and needs cleaning up, but I don't immediately see /* This is ugly and needs cleaning up, but I don't immediately see
how whilst remaining safe. */ how whilst remaining safe. */
static int static int
totalExponent(const char *p, int exponentAdjustment) totalExponent(StringRef::iterator p, StringRef::iterator end,
int exponentAdjustment)
{ {
int unsignedExponent; int unsignedExponent;
bool negative, overflow; bool negative, overflow;
@ -175,14 +182,12 @@ totalExponent(const char *p, int exponentAdjustment)
unsignedExponent = 0; unsignedExponent = 0;
overflow = false; overflow = false;
for(;;) { for(; p != end; ++p) {
unsigned int value; unsigned int value;
value = decDigitValue(*p); value = decDigitValue(*p);
if(value >= 10U) assert(value < 10U && "Invalid character in exponent");
break;
p++;
unsignedExponent = unsignedExponent * 10 + value; unsignedExponent = unsignedExponent * 10 + value;
if(unsignedExponent > 65535) if(unsignedExponent > 65535)
overflow = true; overflow = true;
@ -206,16 +211,21 @@ totalExponent(const char *p, int exponentAdjustment)
return exponent; return exponent;
} }
static const char * static StringRef::iterator
skipLeadingZeroesAndAnyDot(const char *p, const char **dot) skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end,
StringRef::iterator *dot)
{ {
*dot = 0; StringRef::iterator p = begin;
while(*p == '0') *dot = end;
while(*p == '0' && p != end)
p++; p++;
if(*p == '.') { if(*p == '.') {
*dot = p++; *dot = p++;
while(*p == '0')
assert(end - begin != 1 && "String cannot be just a dot");
while(*p == '0' && p != end)
p++; p++;
} }
@ -243,41 +253,50 @@ struct decimalInfo {
}; };
static void static void
interpretDecimal(const char *p, decimalInfo *D) interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
decimalInfo *D)
{ {
const char *dot; StringRef::iterator dot = end;
StringRef::iterator p = skipLeadingZeroesAndAnyDot (begin, end, &dot);
p = skipLeadingZeroesAndAnyDot (p, &dot);
D->firstSigDigit = p; D->firstSigDigit = p;
D->exponent = 0; D->exponent = 0;
D->normalizedExponent = 0; D->normalizedExponent = 0;
for (;;) { for (; p != end; ++p) {
if (*p == '.') { if (*p == '.') {
assert(dot == 0); assert(dot == end && "Multiple dots in float");
dot = p++; dot = p++;
if (p == end)
break;
} }
if (decDigitValue(*p) >= 10U) if (decDigitValue(*p) >= 10U)
break; break;
p++;
} }
/* If number is all zerooes accept any exponent. */ if (p != end) {
if (p != D->firstSigDigit) { assert((*p == 'e' || *p == 'E') && "Invalid character in digit string");
if (*p == 'e' || *p == 'E')
D->exponent = readExponent(p + 1); /* p points to the first non-digit in the string */
if (*p == 'e' || *p == 'E') {
D->exponent = readExponent(p + 1, end);
}
/* Implied decimal point? */ /* Implied decimal point? */
if (!dot) if (dot == end)
dot = p; dot = p;
}
/* If number is all zeroes accept any exponent. */
if (p != D->firstSigDigit) {
/* Drop insignificant trailing zeroes. */ /* Drop insignificant trailing zeroes. */
do if (p != begin) {
do do
p--; do
while (*p == '0'); p--;
while (*p == '.'); while (p != begin && *p == '0');
while (p != begin && *p == '.');
}
/* Adjust the exponents for any decimal point. */ /* Adjust the exponents for any decimal point. */
D->exponent += static_cast<exponent_t>((dot - p) - (dot > p)); D->exponent += static_cast<exponent_t>((dot - p) - (dot > p));
@ -293,7 +312,8 @@ interpretDecimal(const char *p, decimalInfo *D)
DIGITVALUE is the first hex digit of the fraction, P points to DIGITVALUE is the first hex digit of the fraction, P points to
the next digit. */ the next digit. */
static lostFraction static lostFraction
trailingHexadecimalFraction(const char *p, unsigned int digitValue) trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
unsigned int digitValue)
{ {
unsigned int hexDigit; unsigned int hexDigit;
@ -308,6 +328,8 @@ trailingHexadecimalFraction(const char *p, unsigned int digitValue)
while(*p == '0') while(*p == '0')
p++; p++;
assert(p != end && "Invalid trailing hexadecimal fraction!");
hexDigit = hexDigitValue(*p); hexDigit = hexDigitValue(*p);
/* If we ran off the end it is exactly zero or one-half, otherwise /* If we ran off the end it is exactly zero or one-half, otherwise
@ -681,7 +703,7 @@ APFloat::APFloat(const fltSemantics &ourSemantics,
makeNaN(type); makeNaN(type);
} }
APFloat::APFloat(const fltSemantics &ourSemantics, const char *text) APFloat::APFloat(const fltSemantics &ourSemantics, const StringRef& text)
{ {
assertArithmeticOK(ourSemantics); assertArithmeticOK(ourSemantics);
initialize(&ourSemantics); initialize(&ourSemantics);
@ -2107,13 +2129,13 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts,
} }
APFloat::opStatus APFloat::opStatus
APFloat::convertFromHexadecimalString(const char *p, APFloat::convertFromHexadecimalString(const StringRef &s,
roundingMode rounding_mode) roundingMode rounding_mode)
{ {
lostFraction lost_fraction; lostFraction lost_fraction;
integerPart *significand; integerPart *significand;
unsigned int bitPos, partsCount; unsigned int bitPos, partsCount;
const char *dot, *firstSignificantDigit; StringRef::iterator dot, firstSignificantDigit;
zeroSignificand(); zeroSignificand();
exponent = 0; exponent = 0;
@ -2124,10 +2146,10 @@ APFloat::convertFromHexadecimalString(const char *p,
bitPos = partsCount * integerPartWidth; bitPos = partsCount * integerPartWidth;
/* Skip leading zeroes and any (hexa)decimal point. */ /* Skip leading zeroes and any (hexa)decimal point. */
p = skipLeadingZeroesAndAnyDot(p, &dot); StringRef::iterator p = skipLeadingZeroesAndAnyDot(s.begin(), s.end(), &dot);
firstSignificantDigit = p; firstSignificantDigit = p;
for(;;) { for(; p != s.end();) {
integerPart hex_value; integerPart hex_value;
if(*p == '.') { if(*p == '.') {
@ -2143,21 +2165,26 @@ APFloat::convertFromHexadecimalString(const char *p,
p++; p++;
/* Store the number whilst 4-bit nibbles remain. */ if (p == s.end()) {
if(bitPos) {
bitPos -= 4;
hex_value <<= bitPos % integerPartWidth;
significand[bitPos / integerPartWidth] |= hex_value;
} else {
lost_fraction = trailingHexadecimalFraction(p, hex_value);
while(hexDigitValue(*p) != -1U)
p++;
break; break;
} else {
/* Store the number whilst 4-bit nibbles remain. */
if(bitPos) {
bitPos -= 4;
hex_value <<= bitPos % integerPartWidth;
significand[bitPos / integerPartWidth] |= hex_value;
} else {
lost_fraction = trailingHexadecimalFraction(p, s.end(), hex_value);
while(p != s.end() && hexDigitValue(*p) != -1U)
p++;
break;
}
} }
} }
/* Hex floats require an exponent but not a hexadecimal point. */ /* Hex floats require an exponent but not a hexadecimal point. */
assert(*p == 'p' || *p == 'P'); assert(p != s.end() && (*p == 'p' || *p == 'P') &&
"Hex strings require an exponent");
/* Ignore the exponent if we are zero. */ /* Ignore the exponent if we are zero. */
if(p != firstSignificantDigit) { if(p != firstSignificantDigit) {
@ -2180,7 +2207,7 @@ APFloat::convertFromHexadecimalString(const char *p,
expAdjustment -= partsCount * integerPartWidth; expAdjustment -= partsCount * integerPartWidth;
/* Adjust for the given exponent. */ /* Adjust for the given exponent. */
exponent = totalExponent(p, expAdjustment); exponent = totalExponent(p, s.end(), expAdjustment);
} }
return normalize(rounding_mode, lost_fraction); return normalize(rounding_mode, lost_fraction);
@ -2272,13 +2299,14 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
} }
APFloat::opStatus APFloat::opStatus
APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode) APFloat::convertFromDecimalString(const StringRef &str, roundingMode rounding_mode)
{ {
decimalInfo D; decimalInfo D;
opStatus fs; opStatus fs;
/* Scan the text. */ /* Scan the text. */
interpretDecimal(p, &D); StringRef::iterator p = str.begin();
interpretDecimal(p, str.end(), &D);
/* Handle the quick cases. First the case of no significant digits, /* Handle the quick cases. First the case of no significant digits,
i.e. zero, and then exponents that are obviously too large or too i.e. zero, and then exponents that are obviously too large or too
@ -2333,10 +2361,14 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode)
multiplier = 1; multiplier = 1;
do { do {
if (*p == '.') if (*p == '.') {
p++; p++;
if (p == str.end()) {
break;
}
}
decValue = decDigitValue(*p++); decValue = decDigitValue(*p++);
assert(decValue < 10U && "Invalid character in digit string");
multiplier *= 10; multiplier *= 10;
val = val * 10 + decValue; val = val * 10 + decValue;
/* The maximum number that can be multiplied by ten with any /* The maximum number that can be multiplied by ten with any
@ -2364,20 +2396,31 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode)
} }
APFloat::opStatus APFloat::opStatus
APFloat::convertFromString(const char *p, roundingMode rounding_mode) APFloat::convertFromString(const StringRef &str, roundingMode rounding_mode)
{ {
assertArithmeticOK(*semantics); assertArithmeticOK(*semantics);
assert(!str.empty() && "Invalid string length");
/* Handle a leading minus sign. */ /* Handle a leading minus sign. */
if(*p == '-') StringRef::iterator p = str.begin();
sign = 1, p++; size_t slen = str.size();
else unsigned isNegative = str.front() == '-';
if(isNegative) {
sign = 1;
p++;
slen--;
assert(slen && "String is only a minus!");
} else {
sign = 0; sign = 0;
}
if(p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) if(slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
return convertFromHexadecimalString(p + 2, rounding_mode); assert(slen - 2 && "Invalid string");
return convertFromHexadecimalString(str.substr(isNegative + 2),
rounding_mode);
}
return convertFromDecimalString(p, rounding_mode); return convertFromDecimalString(str.substr(isNegative), rounding_mode);
} }
/* Write out a hexadecimal representation of the floating point value /* Write out a hexadecimal representation of the floating point value
@ -2744,7 +2787,7 @@ APFloat::bitcastToAPInt() const
float float
APFloat::convertToFloat() const APFloat::convertToFloat() const
{ {
assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); assert(semantics == (const llvm::fltSemantics*)&IEEEsingle && "Float semantics are not IEEEsingle");
APInt api = bitcastToAPInt(); APInt api = bitcastToAPInt();
return api.bitsToFloat(); return api.bitsToFloat();
} }
@ -2752,7 +2795,7 @@ APFloat::convertToFloat() const
double double
APFloat::convertToDouble() const APFloat::convertToDouble() const
{ {
assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); assert(semantics == (const llvm::fltSemantics*)&IEEEdouble && "Float semantics are not IEEEdouble");
APInt api = bitcastToAPInt(); APInt api = bitcastToAPInt();
return api.bitsToDouble(); return api.bitsToDouble();
} }

View File

@ -0,0 +1,106 @@
//===- llvm/unittest/ADT/APFloat.cpp - APFloat unit tests ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <ostream>
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallString.h"
using namespace llvm;
namespace {
TEST(APFloatTest, Zero) {
ASSERT_EQ(0.0f, APFloat(APFloat::IEEEsingle, 0.0f).convertToFloat());
ASSERT_EQ(-0.0f, APFloat(APFloat::IEEEsingle, -0.0f).convertToFloat());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, 0.0).convertToDouble());
ASSERT_EQ(-0.0, APFloat(APFloat::IEEEdouble, -0.0).convertToDouble());
}
TEST(APFloatTest, SemanticsDeath) {
ASSERT_DEATH(APFloat(APFloat::IEEEsingle, 0.0f).convertToDouble(), "Float semantics are not IEEEdouble");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, 0.0 ).convertToFloat(), "Float semantics are not IEEEsingle");
}
TEST(APFloatTest, fromString) {
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0.").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, ".0").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0.0").convertToDouble());
ASSERT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0").convertToDouble());
ASSERT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.").convertToDouble());
ASSERT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.0").convertToDouble());
ASSERT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.0").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0e1234").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0e1234").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "00000.").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0000.00000").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, ".00000").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0.").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0.e1").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0.e+1").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0.e-1").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "000.0000e0").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "000.0000e-0").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "000.0000e1234").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "000.0000e-1234").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x0p1").convertToDouble());
ASSERT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p1").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x00000.p1").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x0000.00000p1").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x.00000p1").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x0.p1").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x0p1234").convertToDouble());
ASSERT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p1234").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x00000.p1234").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x0000.00000p1234").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x.00000p1234").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, "0x0.p1234").convertToDouble());
ASSERT_EQ(0.0, APFloat(APFloat::IEEEdouble, StringRef("0e1\02", 3)).convertToDouble());
}
TEST(APFloatTest, StringDeath) {
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, ""), "Invalid string length");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "-"), "String is only a minus!");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "0x"), "Invalid string");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "."), "String cannot be just a dot");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "-."), "String cannot be just a dot");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "0x."), "String cannot be just a dot");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "-0x."),"String cannot be just a dot");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "0x0"), "Hex strings require an exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "0e"), "Exponent has no digits");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "0e+"), "Exponent has no digits");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "0e-"), "Exponent has no digits");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("\0", 1)), "Invalid character in digit string");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1\0", 2)), "Invalid character in digit string");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1\02", 3)), "Invalid character in digit string");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1\02e1", 5)), "Invalid character in digit string");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1e\0", 3)), "Invalid character in exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1e1\0", 4)), "Invalid character in exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1e1\02", 5)), "Invalid character in exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "1.0f"), "Invalid character in digit string");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x\0", 3)), "Hex strings require an exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1\0", 4)), "Hex strings require an exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1\02", 5)), "Hex strings require an exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1\02p1", 7)), "Hex strings require an exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1p\0", 5)), "Invalid character in exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1p1\0", 6)), "Invalid character in exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1p1\02", 7)), "Invalid character in exponent");
ASSERT_DEATH(APFloat(APFloat::IEEEdouble, "0x1p0f"), "Invalid character in exponent");
}
}