diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index 5026c83433a3..ab5d05969ede 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -387,16 +387,24 @@ EmitOCUVectorElementExpr(const OCUVectorElementExpr *E) { LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { + bool isUnion = false; Expr *BaseExpr = E->getBase(); llvm::Value *BaseValue = NULL; // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar. - if (E->isArrow()) + if (E->isArrow()) { BaseValue = EmitScalarExpr(BaseExpr); + const PointerType *PTy = + cast(BaseExpr->getType().getCanonicalType()); + if (PTy->getPointeeType()->isUnionType()) + isUnion = true; + } else { LValue BaseLV = EmitLValue(BaseExpr); // FIXME: this isn't right for bitfields. BaseValue = BaseLV.getAddress(); + if (BaseExpr->getType()->isUnionType()) + isUnion = true; } FieldDecl *Field = E->getMemberDecl(); @@ -409,7 +417,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { llvm::Value *V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp"); // Match union field type. - if (BaseExpr->getType()->isUnionType()) { + if (isUnion) { const llvm::Type * FieldTy = ConvertType(Field->getType()); const llvm::PointerType * BaseTy = cast(BaseValue->getType()); diff --git a/clang/test/CodeGen/union.c b/clang/test/CodeGen/union.c index 473293847c0a..4d32abdf54df 100644 --- a/clang/test/CodeGen/union.c +++ b/clang/test/CodeGen/union.c @@ -1,6 +1,6 @@ // RUN: clang %s -emit-llvm -union { +union u_tag { int a; float b; } u; @@ -9,6 +9,10 @@ void f() { u.b = 11; } +float get_b(union u_tag *my_u) { + return my_u->b; +} + int f2( float __x ) { union{ float __f;