r205217 - MS ABI: Use the proper type for inalloca args

David Majnemer david.majnemer at gmail.com
Mon Mar 31 09:12:47 PDT 2014


Author: majnemer
Date: Mon Mar 31 11:12:47 2014
New Revision: 205217

URL: http://llvm.org/viewvc/llvm-project?rev=205217&view=rev
Log:
MS ABI: Use the proper type for inalloca args

Summary:
The definition of a type later in a translation unit may change it's
type from {}* to (%struct.foo*)*.  Earlier function definitions may use
the former while more recent definitions might use the later.  This is
fine until they interact with one another (like one calling the other).
In these cases, a bitcast is needed because the inalloca must match the
function call but the store to the lvalue which initializes the argument
slot has to match the rvalue's type.

This technique is along the same lines with what the other,
non-inalloca, codepaths perform.

This fixes PR19287.

Reviewers: rnk

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D3224

Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=205217&r1=205216&r2=205217&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Mar 31 11:12:47 2014
@@ -2603,6 +2603,13 @@ RValue CodeGenFunction::EmitCall(const C
         // Store the RValue into the argument struct.
         llvm::Value *Addr =
             Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex());
+        unsigned AS = Addr->getType()->getPointerAddressSpace();
+        llvm::Type *MemType = ConvertTypeForMem(I->Ty)->getPointerTo(AS);
+        // There are some cases where a trivial bitcast is not avoidable.  The
+        // definition of a type later in a translation unit may change it's type
+        // from {}* to (%struct.foo*)*.
+        if (Addr->getType() != MemType)
+          Addr = Builder.CreateBitCast(Addr, MemType);
         LValue argLV = MakeAddrLValue(Addr, I->Ty, TypeAlign);
         EmitInitStoreOfNonAggregate(*this, RV, argLV);
       }

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp?rev=205217&r1=205216&r2=205217&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp Mon Mar 31 11:12:47 2014
@@ -263,3 +263,23 @@ void bar() {
 // WIN32: }
 
 }
+
+// We would crash here because the later definition of ForwardDeclare1 results
+// in a different IR type for the value we want to store.  However, the alloca's
+// type will use the argument type selected by fn1.
+struct ForwardDeclare1;
+
+typedef void (*FnPtr1)(ForwardDeclare1);
+void fn1(FnPtr1, SmallWithDtor) {}
+
+struct ForwardDeclare1 {};
+
+void fn2() { fn1(0, SmallWithDtor()); };
+// WIN32-LABEL: define void @"\01?fn2@@YAXXZ"
+// WIN32:   %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty:<{ {}\*, %struct.SmallWithDtor }>]]
+// WIN32:   getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// WIN32:   call x86_thiscallcc %struct.SmallWithDtor* @"\01??0SmallWithDtor@@QAE at XZ"(%struct.SmallWithDtor* %0)
+// WIN32:   getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0
+// WIN32:   %[[addr:[^ ]*]] = bitcast {}** %1 to void [[dst_ty:\(%struct.ForwardDeclare1\*\)\*]]*
+// WIN32:   store void [[dst_ty]] null, void [[dst_ty]]* %[[addr]], align 4
+// WIN32:   call void @"\01?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca %[[argmem]])





More information about the cfe-commits mailing list