]> granicus.if.org Git - clang/commitdiff
CodeGen: _Atomic(_Complex) shouldn't crash
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 14 Feb 2015 01:48:17 +0000 (01:48 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 14 Feb 2015 01:48:17 +0000 (01:48 +0000)
We could be a little kinder if we did a compare-exchange loop instead of
an atomic-load/store pair.

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

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprComplex.cpp
test/CodeGen/atomic_ops.c

index ead8531c5f196dcedf76c549177abaf28eab5eb8..cf23e6dc9e125faf51f1fd3f79a299462fb11384 100644 (file)
@@ -820,10 +820,14 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
     return EmitObjCIsaExpr(cast<ObjCIsaExpr>(E));
   case Expr::BinaryOperatorClass:
     return EmitBinaryOperatorLValue(cast<BinaryOperator>(E));
-  case Expr::CompoundAssignOperatorClass:
-    if (!E->getType()->isAnyComplexType())
+  case Expr::CompoundAssignOperatorClass: {
+    QualType Ty = E->getType();
+    if (const AtomicType *AT = Ty->getAs<AtomicType>())
+      Ty = AT->getValueType();
+    if (!Ty->isAnyComplexType())
       return EmitCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
     return EmitComplexCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
+  }
   case Expr::CallExprClass:
   case Expr::CXXMemberCallExprClass:
   case Expr::CXXOperatorCallExprClass:
index 1fea5a127c0957fda5f9e2ebc3729bddf0418a22..e0ac08b1aa6dbfd3c512e5acdf6b226a2a4abcaa 100644 (file)
@@ -820,6 +820,8 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
   TestAndClearIgnoreReal();
   TestAndClearIgnoreImag();
   QualType LHSTy = E->getLHS()->getType();
+  if (const AtomicType *AT = LHSTy->getAs<AtomicType>())
+    LHSTy = AT->getValueType();
 
   BinOpInfo OpInfo;
 
index 5f2a1966a2a73fe56e6c33ad1d2f7ba79b04bf60..4f9bc410376c86364b4c2f339e70f1894c88ce71 100644 (file)
@@ -26,3 +26,11 @@ _Bool bar() {
 // CHECK: ret i1 %[[tobool]]
   return b;
 }
+
+extern _Atomic(_Complex int) x;
+
+void baz(int y) {
+// CHECK-LABEL: @baz
+// CHECK: store atomic
+  x += y;
+}