CodeGen: use COMDAT for block copy/destroy helpers
SVN r339438 added support to deduplicate the helpers by using a consistent
naming scheme and using LinkOnceODR semantics. This works on ELF by means of
weak linking semantics, and entirely does not work on PE/COFF where you end up
with multiply defined strong symbols, which is a strong error on PE/COFF.
Assign the functions a COMDAT group so that they can be uniqued by the linker.
This fixes the use of blocks in CoreFoundation on Windows.
llvm-svn: 354678
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index f4f5f6f..1c10c46 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -2016,6 +2016,8 @@
llvm::Function *Fn =
llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
FuncName, &CGM.getModule());
+ if (CGM.supportsCOMDAT())
+ Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));
IdentifierInfo *II = &C.Idents.get(FuncName);
@@ -2207,6 +2209,8 @@
llvm::Function *Fn =
llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
FuncName, &CGM.getModule());
+ if (CGM.supportsCOMDAT())
+ Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));
IdentifierInfo *II = &C.Idents.get(FuncName);
diff --git a/clang/test/CodeGen/blocks-1.c b/clang/test/CodeGen/blocks-1.c
index 8589a7b..0df1379 100644
--- a/clang/test/CodeGen/blocks-1.c
+++ b/clang/test/CodeGen/blocks-1.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o %t -fblocks
+// RUN: %clang_cc1 -triple thumbv7-apple-ios %s -emit-llvm -o %t -fblocks
// RUN: grep "_Block_object_dispose" %t | count 12
// RUN: grep "__copy_helper_block_" %t | count 9
// RUN: grep "__destroy_helper_block_" %t | count 9
@@ -7,6 +7,15 @@
// RUN: grep "i32 135)" %t | count 2
// RUN: grep "_Block_object_assign" %t | count 5
+// RUN: %clang_cc1 -triple thumbv7-unknown-windows %s -emit-llvm -o %t -fblocks
+// RUN: grep "_Block_object_dispose" %t | count 12
+// RUN: grep "__copy_helper_block_" %t | count 11
+// RUN: grep "__destroy_helper_block_" %t | count 11
+// RUN: grep "__Block_byref_object_copy_" %t | count 2
+// RUN: grep "__Block_byref_object_dispose_" %t | count 2
+// RUN: grep "i32 135)" %t | count 2
+// RUN: grep "_Block_object_assign" %t | count 5
+
int printf(const char *, ...);
void test1() {