]> granicus.if.org Git - clang/commitdiff
CodeGen: handle blocks correctly when inalloca'ed
authorSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 21 Feb 2018 21:47:51 +0000 (21:47 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 21 Feb 2018 21:47:51 +0000 (21:47 +0000)
When using blocks with C++ on Windows x86, it is possible to have the
block literal be pushed into the inalloca'ed parameters.  Teach IRGen to
handle the case properly by extracting the block literal from the
inalloca parameter.  This fixes the use of blocks with C++ on Windows
x86.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325724 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDecl.cpp
test/CodeGenCXX/block-inalloca.cpp [new file with mode: 0644]

index c036cd414e40eb9bfb470030e6beb672bb911c5c..19cdc24270ce2b9ee956a553d04ccf7b77a14333 100644 (file)
@@ -1848,9 +1848,12 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
   // Use better IR generation for certain implicit parameters.
   if (auto IPD = dyn_cast<ImplicitParamDecl>(&D)) {
     // The only implicit argument a block has is its literal.
-    // We assume this is always passed directly.
+    // This may be passed as an inalloca'ed value on Windows x86.
     if (BlockInfo) {
-      setBlockContextParameter(IPD, ArgNo, Arg.getDirectValue());
+      llvm::Value *V = Arg.isIndirect()
+                           ? Builder.CreateLoad(Arg.getIndirectAddress())
+                           : Arg.getDirectValue();
+      setBlockContextParameter(IPD, ArgNo, V);
       return;
     }
   }
diff --git a/test/CodeGenCXX/block-inalloca.cpp b/test/CodeGenCXX/block-inalloca.cpp
new file mode 100644 (file)
index 0000000..b827dde
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fblocks -emit-llvm -o - %s | FileCheck %s
+
+struct S {
+  S(const struct S &) {}
+};
+
+void (^b)(S) = ^(S) {};
+
+// CHECK: [[DESCRIPTOR:%.*]] = getelementptr inbounds <{ i8*, %struct.S, [3 x i8] }>, <{ i8*, %struct.S, [3 x i8] }>* %0, i32 0, i32 0
+// CHECK: load i8*, i8** [[DESCRIPTOR]]
+