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

Reply via email to