[cfe-commits] r81251 - in /cfe/trunk: include/clang/AST/APValue.h lib/AST/APValue.cpp

Douglas Gregor dgregor at apple.com
Tue Sep 8 12:57:34 PDT 2009


Author: dgregor
Date: Tue Sep  8 14:57:33 2009
New Revision: 81251

URL: http://llvm.org/viewvc/llvm-project?rev=81251&view=rev
Log:
Make sure to access APValue's data via a char array (rather than
through an array of void*), so that we don't run afoul of the
strict-aliasing rules in C++ 3.10p15. Unfortunately, GCC 4.4 still
complains about this code.


Modified:
    cfe/trunk/include/clang/AST/APValue.h
    cfe/trunk/lib/AST/APValue.cpp

Modified: cfe/trunk/include/clang/AST/APValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/APValue.h?rev=81251&r1=81250&r2=81251&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/APValue.h (original)
+++ cfe/trunk/include/clang/AST/APValue.h Tue Sep  8 14:57:33 2009
@@ -62,11 +62,12 @@
     MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ? 
                sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
   };
-  
-  /// Data - space for the largest member in units of void*.  This is an effort
-  /// to ensure that the APSInt/APFloat values have proper alignment.
-  void *Data[(MaxSize+sizeof(void*)-1)/sizeof(void*)];
-  
+
+  union {
+    void *Aligner;
+    char Data[MaxSize];
+  };
+
 public:
   APValue() : Kind(Uninitialized) {}
   explicit APValue(const APSInt &I) : Kind(Uninitialized) {
@@ -108,7 +109,7 @@
   
   APSInt &getInt() {
     assert(isInt() && "Invalid accessor");
-    return *(APSInt*)(void*)Data;
+    return *(APSInt*)(char*)Data;
   }
   const APSInt &getInt() const {
     return const_cast<APValue*>(this)->getInt();
@@ -116,7 +117,7 @@
   
   APFloat &getFloat() {
     assert(isFloat() && "Invalid accessor");
-    return *(APFloat*)(void*)Data;
+    return *(APFloat*)(char*)Data;
   }
   const APFloat &getFloat() const {
     return const_cast<APValue*>(this)->getFloat();
@@ -124,7 +125,7 @@
   
   APValue &getVectorElt(unsigned i) const {
     assert(isVector() && "Invalid accessor");
-    return ((Vec*)(void*)Data)->Elts[i];
+    return ((Vec*)(char*)Data)->Elts[i];
   }
   unsigned getVectorLength() const {
     assert(isVector() && "Invalid accessor");
@@ -133,7 +134,7 @@
   
   APSInt &getComplexIntReal() {
     assert(isComplexInt() && "Invalid accessor");
-    return ((ComplexAPSInt*)(void*)Data)->Real;
+    return ((ComplexAPSInt*)(char*)Data)->Real;
   }
   const APSInt &getComplexIntReal() const {
     return const_cast<APValue*>(this)->getComplexIntReal();
@@ -141,7 +142,7 @@
   
   APSInt &getComplexIntImag() {
     assert(isComplexInt() && "Invalid accessor");
-    return ((ComplexAPSInt*)(void*)Data)->Imag;
+    return ((ComplexAPSInt*)(char*)Data)->Imag;
   }
   const APSInt &getComplexIntImag() const {
     return const_cast<APValue*>(this)->getComplexIntImag();
@@ -149,7 +150,7 @@
   
   APFloat &getComplexFloatReal() {
     assert(isComplexFloat() && "Invalid accessor");
-    return ((ComplexAPFloat*)(void*)Data)->Real;
+    return ((ComplexAPFloat*)(char*)Data)->Real;
   }
   const APFloat &getComplexFloatReal() const {
     return const_cast<APValue*>(this)->getComplexFloatReal();
@@ -157,7 +158,7 @@
 
   APFloat &getComplexFloatImag() {
     assert(isComplexFloat() && "Invalid accessor");
-    return ((ComplexAPFloat*)(void*)Data)->Imag;
+    return ((ComplexAPFloat*)(char*)Data)->Imag;
   }
   const APFloat &getComplexFloatImag() const {
     return const_cast<APValue*>(this)->getComplexFloatImag();
@@ -174,37 +175,37 @@
   
   void setInt(const APSInt &I) {
     assert(isInt() && "Invalid accessor");
-    *(APSInt*)(void*)Data = I;
+    *(APSInt*)(char*)Data = I;
   }
   void setFloat(const APFloat &F) {
     assert(isFloat() && "Invalid accessor");
-    *(APFloat*)(void*)Data = F;
+    *(APFloat*)(char*)Data = F;
   }
   void setVector(const APValue *E, unsigned N) {
     assert(isVector() && "Invalid accessor");
-    ((Vec*)(void*)Data)->Elts = new APValue[N];
-    ((Vec*)(void*)Data)->NumElts = N;
+    ((Vec*)(char*)Data)->Elts = new APValue[N];
+    ((Vec*)(char*)Data)->NumElts = N;
     for (unsigned i = 0; i != N; ++i)
-      ((Vec*)(void*)Data)->Elts[i] = E[i];
+      ((Vec*)(char*)Data)->Elts[i] = E[i];
   }
   void setComplexInt(const APSInt &R, const APSInt &I) {
     assert(R.getBitWidth() == I.getBitWidth() && 
            "Invalid complex int (type mismatch).");
     assert(isComplexInt() && "Invalid accessor");
-    ((ComplexAPSInt*)(void*)Data)->Real = R;
-    ((ComplexAPSInt*)(void*)Data)->Imag = I;
+    ((ComplexAPSInt*)(char*)Data)->Real = R;
+    ((ComplexAPSInt*)(char*)Data)->Imag = I;
   }
   void setComplexFloat(const APFloat &R, const APFloat &I) {
     assert(&R.getSemantics() == &I.getSemantics() && 
            "Invalid complex float (type mismatch).");
     assert(isComplexFloat() && "Invalid accessor");
-    ((ComplexAPFloat*)(void*)Data)->Real = R;
-    ((ComplexAPFloat*)(void*)Data)->Imag = I;
+    ((ComplexAPFloat*)(char*)Data)->Real = R;
+    ((ComplexAPFloat*)(char*)Data)->Imag = I;
   }
   void setLValue(Expr *B, uint64_t O) {
     assert(isLValue() && "Invalid accessor");
-    ((LV*)(void*)Data)->Base = B;
-    ((LV*)(void*)Data)->Offset = O;
+    ((LV*)(char*)Data)->Base = B;
+    ((LV*)(char*)Data)->Offset = O;
   }
   
   const APValue &operator=(const APValue &RHS);
@@ -218,27 +219,27 @@
   }
   void MakeFloat() {
     assert(isUninit() && "Bad state change");
-    new ((APFloat*)(void*)Data) APFloat(0.0);
+    new ((void*)(char*)Data) APFloat(0.0);
     Kind = Float;
   }
   void MakeVector() {
     assert(isUninit() && "Bad state change");
-    new ((Vec*)(void*)Data) Vec();
+    new ((void*)(char*)Data) Vec();
     Kind = Vector;
   }
   void MakeComplexInt() {
     assert(isUninit() && "Bad state change");
-    new ((ComplexAPSInt*)(void*)Data) ComplexAPSInt();
+    new ((void*)(char*)Data) ComplexAPSInt();
     Kind = ComplexInt;
   }
   void MakeComplexFloat() {
     assert(isUninit() && "Bad state change");
-    new ((ComplexAPFloat*)(void*)Data) ComplexAPFloat();
+    new ((void*)(char*)Data) ComplexAPFloat();
     Kind = ComplexFloat;
   }
   void MakeLValue() {
     assert(isUninit() && "Bad state change");
-    new ((LV*)(void*)Data) LV();
+    new ((void*)(char*)Data) LV();
     Kind = LValue;
   }
 };

Modified: cfe/trunk/lib/AST/APValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/APValue.cpp?rev=81251&r1=81250&r2=81251&view=diff

==============================================================================
--- cfe/trunk/lib/AST/APValue.cpp (original)
+++ cfe/trunk/lib/AST/APValue.cpp Tue Sep  8 14:57:33 2009
@@ -37,7 +37,7 @@
   else if (isFloat())
     setFloat(RHS.getFloat());
   else if (isVector())
-    setVector(((Vec*)(void*)RHS.Data)->Elts, RHS.getVectorLength());
+    setVector(((Vec*)(char*)RHS.Data)->Elts, RHS.getVectorLength());
   else if (isComplexInt())
     setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
   else if (isComplexFloat())
@@ -49,17 +49,17 @@
 
 void APValue::MakeUninit() {
   if (Kind == Int)
-    ((APSInt*)(void*)Data)->~APSInt();
+    ((APSInt*)(char*)Data)->~APSInt();
   else if (Kind == Float)
-    ((APFloat*)(void*)Data)->~APFloat();
+    ((APFloat*)(char*)Data)->~APFloat();
   else if (Kind == Vector)
-    ((Vec*)(void*)Data)->~Vec();
+    ((Vec*)(char*)Data)->~Vec();
   else if (Kind == ComplexInt)
-    ((ComplexAPSInt*)(void*)Data)->~ComplexAPSInt();
+    ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
   else if (Kind == ComplexFloat)
-    ((ComplexAPFloat*)(void*)Data)->~ComplexAPFloat();
+    ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
   else if (Kind == LValue) {
-    ((LV*)(void*)Data)->~LV();
+    ((LV*)(char*)Data)->~LV();
   }
   Kind = Uninitialized;
 }





More information about the cfe-commits mailing list