summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-03-31 16:12:47 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-03-31 16:12:47 +0000
commit68d4885b9f26aeae42101f5215b20e80b14d17fb (patch)
treef60941f165abde27fda651d288e1ea126aeb54c6 /test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
parent03a5eb39a60ec31f37daa074ad1c94797a1ca854 (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205217 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp')
-rw-r--r--test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index 67cd98a34b..216c6f28c2 100644
--- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -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@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]])