<div dir="ltr">Hi,<div>Please find the patch for incorrect ABI in case we have a union argument passed by value.</div><div><br></div><div>Index: test/CodeGen/transparent-union.c<br></div><div><div>===================================================================</div>
<div>--- test/CodeGen/transparent-union.c<span class="" style="white-space:pre"> </span>(revision 188794)</div><div>+++ test/CodeGen/transparent-union.c<span class="" style="white-space:pre"> </span>(working copy)</div><div>
@@ -1,9 +1,7 @@</div><div> // RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -o %t %s</div><div> // RUN: FileCheck < %t %s</div><div>-//</div><div>-// FIXME: Note that we don't currently get the ABI right here. f0() should be</div>
<div>-// f0(i8*).</div><div> </div><div>+</div><div> typedef union {</div><div> void *f0;</div><div> } transp_t0 __attribute__((transparent_union));</div><div>@@ -11,7 +9,7 @@</div><div> void f0(transp_t0 obj);</div><div>
</div><div> // CHECK-LABEL: define void @f1_0(i32* %a0) </div><div>-// CHECK: call void @f0(%union.transp_t0* byval align 4 %{{.*}})</div><div>+// CHECK: call void @f0(i8* %{{.*}})</div><div> // CHECK: call void %{{.*}}(i8* %{{[a-z0-9]*}})</div>
<div> // CHECK: }</div><div> void f1_0(int *a0) {</div><div>Index: lib/CodeGen/TargetInfo.cpp</div><div>===================================================================</div><div>--- lib/CodeGen/TargetInfo.cpp<span class="" style="white-space:pre"> </span>(revision 188794)</div>
<div>+++ lib/CodeGen/TargetInfo.cpp<span class="" style="white-space:pre"> </span>(working copy)</div><div>@@ -325,10 +325,11 @@</div><div> //</div><div> // FIXME: This needs to be generalized to handle classes as well.</div>
<div> const RecordDecl *RD = RT->getDecl();</div><div>- if (!RD->isStruct() || isa<CXXRecordDecl>(RD))</div><div>+ if (!(RD->isStruct() || RD->isUnion()) || isa<CXXRecordDecl>(RD))</div><div> return false;</div>
<div> </div><div> uint64_t Size = 0;</div><div>+ uint64_t CurrentElmtSize = 0;</div><div> </div><div> for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();</div><div> i != e; ++i) {</div>
<div>@@ -343,7 +344,14 @@</div><div> if (FD->isBitField())</div><div> return false;</div><div> </div><div>+ if (!RD->isUnion())</div><div> Size += Context.getTypeSize(FD->getType());</div><div>+ else {</div>
<div>+ //Size of union is size of it's largest element.</div><div>+ CurrentElmtSize = Context.getTypeSize(FD->getType());</div><div>+ if (CurrentElmtSize > Size)</div><div>+ Size = CurrentElmtSize;</div>
<div>+ }</div><div> }</div><div> </div><div> // Make sure there are not any holes in the struct.</div></div><div><br></div><div><br></div><div>Regards</div><div>Karthik Bhat</div>
</div>