]> granicus.if.org Git - clang/commitdiff
Rename CodeGenFunction::EmitMemSetToZero to EmitNullInitialization. Handle setting...
authorAnders Carlsson <andersca@mac.com>
Fri, 21 May 2010 21:45:41 +0000 (21:45 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 21 May 2010 21:45:41 +0000 (21:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104387 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGClass.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/pointers-to-data-members.cpp

index 82c72288d91829b1d1bac29c17bfe566d267ebd5..587a68beb225ca2911beced3920865feeb80bfda 100644 (file)
@@ -465,7 +465,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
                                          /*IsInitializer=*/true);
     CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
   } else if (FieldType->isArrayType() && !MemberInit->getInit()) {
-    CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType());
+    CGF.EmitNullInitialization(LHS.getAddress(), Field->getType());
   } else if (!CGF.hasAggregateLLVMType(Field->getType())) {
     RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit(), true));
     CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
index 74e64e59a5a836b5c039585a8cfcc54d06144577..a4a4bda723d86edf38afcc9a13e9f186f9224c54 100644 (file)
@@ -1844,7 +1844,7 @@ LValue CodeGenFunction::EmitNullInitializationLValue(
                                               const CXXZeroInitValueExpr *E) {
   QualType Ty = E->getType();
   LValue LV = LValue::MakeAddr(CreateMemTemp(Ty), MakeQualifiers(Ty));
-  EmitMemSetToZero(LV.getAddress(), Ty);
+  EmitNullInitialization(LV.getAddress(), Ty);
   return LV;
 }
 
index 3bf2f8a52025f58fbf1a94cd52c73b365436bb8a..4a7e6ecc42d957b407b318c43efa4c0416e05085 100644 (file)
@@ -573,14 +573,10 @@ void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
     llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T));
     CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T);
   } else {
-    // Otherwise, just memset the whole thing to zero.  This is legal
-    // because in LLVM, all default initializers are guaranteed to have a
-    // bit pattern of all zeros.
-    // FIXME: That isn't true for member pointers!
     // There's a potential optimization opportunity in combining
     // memsets; that would be easy for arrays, but relatively
     // difficult for structures with the current code.
-    CGF.EmitMemSetToZero(LV.getAddress(), T);
+    CGF.EmitNullInitialization(LV.getAddress(), T);
   }
 }
 
index 2f70969e94909d73f5c2b54eeb374afc80ad0545..b07a02b5b3c74e4b6193ab4b61e28f3e3852df64 100644 (file)
@@ -123,10 +123,10 @@ public:
     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
   }
   Value *VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
-    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+    return CGF.CGM.EmitNullConstant(E->getType());
   }
   Value *VisitGNUNullExpr(const GNUNullExpr *E) {
-    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+    return CGF.CGM.EmitNullConstant(E->getType());
   }
   Value *VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
     return llvm::ConstantInt::get(ConvertType(E->getType()),
index 674f50234e550ea1464e14d3a5c5ade5bcbe7132..d44c56fcf68dbac676b97fdebc9701b6923c2f69 100644 (file)
@@ -632,7 +632,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
   // Fast enumeration state.
   QualType StateTy = getContext().getObjCFastEnumerationStateType();
   llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
-  EmitMemSetToZero(StatePtr, StateTy);
+  EmitNullInitialization(StatePtr, StateTy);
 
   // Number of elements in the items array.
   static const unsigned NumItems = 16;
index d3bf1645a026f1fbd8739618f3e04c932e17142d..222dcc4b8f5e9d02f93e195662874d05b4e5997a 100644 (file)
@@ -472,7 +472,23 @@ void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type,
   CGM.ErrorUnsupported(S, Type, OmitOnError);
 }
 
-void CodeGenFunction::EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty) {
+void
+CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) {
+  // If the type contains a pointer to data member we can't memset it to zero.
+  // Instead, create a null constant and copy it to the destination.
+  if (CGM.getTypes().ContainsPointerToDataMember(Ty)) {
+    llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty);
+    
+    llvm::GlobalVariable *NullVariable = 
+      new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(),
+                               /*isConstant=*/true, 
+                               llvm::GlobalVariable::PrivateLinkage,
+                               NullConstant, llvm::Twine());
+    EmitAggregateCopy(DestPtr, NullVariable, Ty, /*isVolatile=*/false);
+    return;
+  } 
+  
+
   // Ignore empty classes in C++.
   if (getContext().getLangOptions().CPlusPlus) {
     if (const RecordType *RT = Ty->getAs<RecordType>()) {
@@ -481,6 +497,9 @@ void CodeGenFunction::EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty) {
     }
   }
   
+  // Otherwise, just memset the whole thing to zero.  This is legal
+  // because in LLVM, all default initializers (other than the ones we just
+  // handled above) are guaranteed to have a bit pattern of all zeros.
   const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
   if (DestPtr->getType() != BP)
     DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
index bac05ba70512d02f31648bd3686a5d3781ceb156..8e68949f3023a3f13916398d501668a64142422f 100644 (file)
@@ -747,8 +747,10 @@ public:
   llvm::BlockAddress *GetAddrOfLabel(const LabelStmt *L);
   llvm::BasicBlock *GetIndirectGotoBlock();
 
-  /// EmitMemSetToZero - Generate code to memset a value of the given type to 0.
-  void EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty);
+  /// EmitNullInitialization - Generate code to set a value of the given type to
+  /// null, If the type contains data member pointers, they will be initialized
+  /// to -1 in accordance with the Itanium C++ ABI.
+  void EmitNullInitialization(llvm::Value *DestPtr, QualType Ty);
 
   // EmitVAArg - Generate code to get an argument from the passed in pointer
   // and update it accordingly. The return value is a pointer to the argument.
index cab06dbd3d373fe366cc55c6ca5796975095599f..ac238fb8fc6c7aeefedad92f644863a2190e0252 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s
-
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 -O3 | FileCheck --check-prefix=CHECK-O3 %s
 struct A { int a; int b; };
 struct B { int b; };
 struct C : B, A { };
@@ -118,3 +118,30 @@ A::A() : a() {}
 
 }
 
+namespace PR7139 {
+
+struct pair {
+  int first;
+  int second;
+};
+
+typedef int pair::*ptr_to_member_type;
+
+struct ptr_to_member_struct { 
+  ptr_to_member_type data;
+  int i;
+};
+
+struct A {
+  ptr_to_member_struct a;
+
+  A() : a() {}
+};
+
+// CHECK-O3: define zeroext i1 @_ZN6PR71395checkEv() nounwind readnone
+bool check() {
+  // CHECK-O3: ret i1 true
+  return A().a.data == 0;
+}
+
+}