The attached patch makes FloatingLiteral::getValue() return 128-bit
floating point values in the correct format.
The existing code always returns PPCDoubleDouble floating points
because parameter isIEEE of constructor APFloat::APFloat(const APInt&
api, bool isIEEE) is not being set (default value is false).
Without this patch, clang terminates with the following message when
the attached test is compiled:
clang: llvm/lib/VMCore/Instructions.cpp:1086: void
llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() ==
cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr
must be a pointer to Val type!"' failed.
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 9eff18b..0a763f6 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -22,6 +22,7 @@
#include "clang/AST/ASTVector.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/UsuallyTinyPtrVector.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/APFloat.h"
@@ -1063,7 +1064,12 @@ public:
class APFloatStorage : public APNumericStorage {
public:
- llvm::APFloat getValue() const { return llvm::APFloat(getIntValue()); }
+ llvm::APFloat getValue(ASTContext &C) const {
+ llvm::APInt IntVal = getIntValue();
+ bool IsIEEE = (IntVal.getBitWidth() != 128) ||
+ (&C.getTargetInfo().getLongDoubleFormat() == &llvm::APFloat::IEEEquad);
+ return llvm::APFloat(IntVal, IsIEEE);
+ }
void setValue(ASTContext &C, const llvm::APFloat &Val) {
setIntValue(C, Val.bitcastToAPInt());
}
@@ -1164,6 +1170,7 @@ public:
};
class FloatingLiteral : public Expr {
+ ASTContext &Ctx;
APFloatStorage Num;
bool IsExact : 1;
SourceLocation Loc;
@@ -1171,21 +1178,20 @@ class FloatingLiteral : public Expr {
FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact,
QualType Type, SourceLocation L)
: Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false,
- false, false),
- IsExact(isexact), Loc(L) {
+ false, false), Ctx(C), IsExact(isexact), Loc(L) {
setValue(C, V);
}
/// \brief Construct an empty floating-point literal.
- explicit FloatingLiteral(EmptyShell Empty)
- : Expr(FloatingLiteralClass, Empty), IsExact(false) { }
+ explicit FloatingLiteral(ASTContext &C, EmptyShell Empty)
+ : Expr(FloatingLiteralClass, Empty), Ctx(C), IsExact(false) { }
public:
static FloatingLiteral *Create(ASTContext &C, const llvm::APFloat &V,
bool isexact, QualType Type, SourceLocation L);
static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty);
- llvm::APFloat getValue() const { return Num.getValue(); }
+ llvm::APFloat getValue() const { return Num.getValue(Ctx); }
void setValue(ASTContext &C, const llvm::APFloat &Val) {
Num.setValue(C, Val);
}
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index bbf5411..f87d60f 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -476,7 +476,7 @@ FloatingLiteral::Create(ASTContext &C, const llvm::APFloat &V,
FloatingLiteral *
FloatingLiteral::Create(ASTContext &C, EmptyShell Empty) {
- return new (C) FloatingLiteral(Empty);
+ return new (C) FloatingLiteral(C, Empty);
}
/// getValueAsApproximateDouble - This returns the value as an inaccurate
typedef long double LD;
LD foo0() {
return 2.34L;
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits