]> granicus.if.org Git - clang/commitdiff
Fix some i1/i8 confusion within _Atomic(bool) in IR generation, both
authorDouglas Gregor <dgregor@apple.com>
Thu, 12 Apr 2012 20:42:30 +0000 (20:42 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 12 Apr 2012 20:42:30 +0000 (20:42 +0000)
in general (such an atomic has boolean representation) and
specifically for IR generation of __c11_atomic_init. The latter also
means actually using initialization semantics for this initialization,
rather than just creating a store.

On a related note, make sure we actually put in non-atomic-to-atomic
conversions when performing an implicit conversion sequence. IR
generation is far too kind here, but we still want the ASTs to make
sense.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154612 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenTypes.cpp
lib/Sema/SemaExprCXX.cpp
test/CodeGenCXX/atomicinit.cpp

index 147e7276bc4652aa1d3962afcf25c7200a0bfaba..0c33fb53711193da621411629644df990cfc1cdf 100644 (file)
@@ -867,6 +867,9 @@ static bool hasBooleanRepresentation(QualType Ty) {
   if (const EnumType *ET = Ty->getAs<EnumType>())
     return ET->getDecl()->getIntegerType()->isBooleanType();
 
+  if (const AtomicType *AT = Ty->getAs<AtomicType>())
+    return hasBooleanRepresentation(AT->getValueType());
+
   return false;
 }
 
@@ -1227,7 +1230,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
   // Get the source value, truncated to the width of the bit-field.
   llvm::Value *SrcVal = Src.getScalarVal();
 
-  if (Dst.getType()->isBooleanType())
+  if (hasBooleanRepresentation(Dst.getType()))
     SrcVal = Builder.CreateIntCast(SrcVal, ResLTy, /*IsSigned=*/false);
 
   SrcVal = Builder.CreateAnd(SrcVal, llvm::APInt::getLowBitsSet(ResSizeInBits,
@@ -2843,10 +2846,11 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
   if (E->getOp() == AtomicExpr::AO__c11_atomic_init) {
     assert(!Dest && "Init does not return a value");
     if (!hasAggregateLLVMType(E->getVal1()->getType())) {
-      llvm::StoreInst *Store =
-        Builder.CreateStore(EmitScalarExpr(E->getVal1()), Ptr);
-      Store->setAlignment(Size);
-      Store->setVolatile(E->isVolatile());
+      QualType PointeeType
+        = E->getPtr()->getType()->getAs<PointerType>()->getPointeeType();
+      EmitScalarInit(EmitScalarExpr(E->getVal1()),
+                     LValue::MakeAddr(Ptr, PointeeType, alignChars,
+                                      getContext()));
     } else if (E->getType()->isAnyComplexType()) {
       EmitComplexExprIntoAddr(E->getVal1(), Ptr, E->isVolatile());
     } else {
index b47da73c1d622baaad9c40557585c48ecdcd059f..41fd536b5cc243483bcf5b2b1d152c375c70c3b3 100644 (file)
@@ -556,7 +556,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
   }
 
   case Type::Atomic: {
-    ResultType = ConvertTypeForMem(cast<AtomicType>(Ty)->getValueType());
+    ResultType = ConvertType(cast<AtomicType>(Ty)->getValueType());
     break;
   }
   }
index 41f2116600b92dfc37f067b99dfb59ce1f86fa2c..31a8115f0b484022a5fe1b01a52dfb48ace1475d 100644 (file)
@@ -2765,6 +2765,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
     llvm_unreachable("Improper third standard conversion");
   }
 
+  // If this conversion sequence involved a scalar -> atomic conversion, perform
+  // that conversion now.
+  if (const AtomicType *ToAtomic = ToType->getAs<AtomicType>())
+    if (Context.hasSameType(ToAtomic->getValueType(), From->getType()))
+      From = ImpCastExprToType(From, ToType, CK_NonAtomicToAtomic, VK_RValue, 0,
+                               CCK).take();
+      
   return Owned(From);
 }
 
index 20e46131df5401fd91bf22375ff1aecf09019051..38d012e6a9a1cd4f7c7d2535e113d33e7906a8d7 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -O1 -o - -triple=i686-apple-darwin9 | FileCheck %s
 struct A {
   _Atomic(int) i;
   A(int j);
@@ -21,5 +21,28 @@ _Atomic(B) b;
 // CHECK: define void @_Z11atomic_initR1Ai
 void atomic_init(A& a, int i) {
   // CHECK-NOT: atomic
+  // CHECK: tail call void @_ZN1BC1Ei
   __c11_atomic_init(&b, B(i));
+  // CHECK-NEXT: ret void
 }
+
+// CHECK: define void @_Z16atomic_init_boolPU7_Atomicbb
+void atomic_init_bool(_Atomic(bool) *ab, bool b) {
+  // CHECK-NOT: atomic
+  // CHECK: {{zext i1.*to i8}}
+  // CHECK-NEXT: store i8
+  __c11_atomic_init(ab, b);
+  // CHECK-NEXT: ret void
+}
+
+struct AtomicBoolMember {
+  _Atomic(bool) ab;
+  AtomicBoolMember(bool b);
+};
+
+// CHECK: define void @_ZN16AtomicBoolMemberC2Eb
+// CHECK: {{zext i1.*to i8}}
+// CHECK-NEXT: store i8
+// CHECK-NEXT: ret void
+AtomicBoolMember::AtomicBoolMember(bool b) : ab(b) { }
+