]> granicus.if.org Git - clang/commitdiff
Match union field type when member expression is u->x
authorDevang Patel <dpatel@apple.com>
Tue, 11 Dec 2007 21:33:16 +0000 (21:33 +0000)
committerDevang Patel <dpatel@apple.com>
Tue, 11 Dec 2007 21:33:16 +0000 (21:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44879 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGExpr.cpp
test/CodeGen/union.c

index 5026c83433a3e8884a07d32dba37d0990be0e9b5..ab5d05969edea60b2393b6c7388fe5b98b05a503 100644 (file)
@@ -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<PointerType>(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<llvm::PointerType>(BaseValue->getType());
index 473293847c0a3b280d1edd26edadd9a28ffdf34b..4d32abdf54dff3639cafa8725b58088e329a31e8 100644 (file)
@@ -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;