From 8f37e96206e47808d516401da00e100a960f66aa Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 22 Feb 2019 16:29:50 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354678 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 4 ++++ test/CodeGen/blocks-1.c | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index f4f5f6f8f4..1c10c46baa 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -2016,6 +2016,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { 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 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { 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/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c index 8589a7bedf..0df13790dd 100644 --- a/test/CodeGen/blocks-1.c +++ b/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() { -- 2.40.0