]> granicus.if.org Git - clang/commitdiff
[OPENMP] Fixed codegen for __real/__imag expressions in atomic
authorAlexey Bataev <a.bataev@hotmail.com>
Mon, 7 Nov 2016 18:15:02 +0000 (18:15 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Mon, 7 Nov 2016 18:15:02 +0000 (18:15 +0000)
constructs.

For __real/__imag unary expressions clang emits lvalue with the
associated type from the original complex expression, but not the
underlying builtin integer or float type. This causes crash in codegen
for atomic constructs, if __real/__imag expression are used in atomic
  constructs.

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

lib/CodeGen/CGExpr.cpp
test/OpenMP/atomic_write_codegen.c

index a5eee2e4120e127c558196a0e61e6323d9226dfb..08e1cad53058233a80c0578be2fc4fea8101f04e 100644 (file)
@@ -2276,13 +2276,15 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
       return LV;
     }
 
-    assert(E->getSubExpr()->getType()->isAnyComplexType());
+    QualType T = ExprTy->castAs<ComplexType>()->getElementType();
 
     Address Component =
       (E->getOpcode() == UO_Real
          ? emitAddrOfRealComponent(LV.getAddress(), LV.getType())
          : emitAddrOfImagComponent(LV.getAddress(), LV.getType()));
-    return MakeAddrLValue(Component, ExprTy, LV.getAlignmentSource());
+    LValue ElemLV = MakeAddrLValue(Component, T, LV.getAlignmentSource());
+    ElemLV.getQuals().addQualifiers(LV.getQuals());
+    return ElemLV;
   }
   case UO_PreInc:
   case UO_PreDec: {
index 66172af07e8f4671e0322b106dcafae4bf792e76..050d7a510566ab517549eafb88257e90624fb406 100644 (file)
@@ -78,6 +78,9 @@ float2 float2x;
 register int rix __asm__("esp");
 
 int main() {
+// CHECK: store atomic i32 1, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @civ, i32 0, i32 1) monotonic,
+#pragma omp atomic write
+ __imag(civ) = 1;
 // CHECK: load i8, i8*
 // CHECK: store atomic i8
 #pragma omp atomic write