From: David Majnemer Date: Sat, 14 Feb 2015 01:48:17 +0000 (+0000) Subject: CodeGen: _Atomic(_Complex) shouldn't crash X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=212af641f2b71dbc372b3cfb283b332116c68b26;p=clang CodeGen: _Atomic(_Complex) shouldn't crash 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 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index ead8531c5f..cf23e6dc9e 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -820,10 +820,14 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { return EmitObjCIsaExpr(cast(E)); case Expr::BinaryOperatorClass: return EmitBinaryOperatorLValue(cast(E)); - case Expr::CompoundAssignOperatorClass: - if (!E->getType()->isAnyComplexType()) + case Expr::CompoundAssignOperatorClass: { + QualType Ty = E->getType(); + if (const AtomicType *AT = Ty->getAs()) + Ty = AT->getValueType(); + if (!Ty->isAnyComplexType()) return EmitCompoundAssignmentLValue(cast(E)); return EmitComplexCompoundAssignmentLValue(cast(E)); + } case Expr::CallExprClass: case Expr::CXXMemberCallExprClass: case Expr::CXXOperatorCallExprClass: diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 1fea5a127c..e0ac08b1aa 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -820,6 +820,8 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E, TestAndClearIgnoreReal(); TestAndClearIgnoreImag(); QualType LHSTy = E->getLHS()->getType(); + if (const AtomicType *AT = LHSTy->getAs()) + LHSTy = AT->getValueType(); BinOpInfo OpInfo; diff --git a/test/CodeGen/atomic_ops.c b/test/CodeGen/atomic_ops.c index 5f2a1966a2..4f9bc41037 100644 --- a/test/CodeGen/atomic_ops.c +++ b/test/CodeGen/atomic_ops.c @@ -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; +}