From 659e828fcc26321f1c98c29f1e7b99b29ec0a32e Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Mon, 7 Nov 2016 18:15:02 +0000 Subject: [PATCH] [OPENMP] Fixed codegen for __real/__imag expressions in atomic 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 | 6 ++++-- test/OpenMP/atomic_write_codegen.c | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index a5eee2e412..08e1cad530 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2276,13 +2276,15 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) { return LV; } - assert(E->getSubExpr()->getType()->isAnyComplexType()); + QualType T = ExprTy->castAs()->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: { diff --git a/test/OpenMP/atomic_write_codegen.c b/test/OpenMP/atomic_write_codegen.c index 66172af07e..050d7a5105 100644 --- a/test/OpenMP/atomic_write_codegen.c +++ b/test/OpenMP/atomic_write_codegen.c @@ -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 -- 2.40.0