From cec02ff66bdc018e7825cb8559210447621f3d30 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Mon, 25 Sep 2017 14:36:11 -0700 Subject: [PATCH] [4.0] IRGen: Fix linkage for shared declarations They need external linkage not linkonce_odr which can only be used by defintions not declarations. This got exposed by clang imported protocol witness table declarations. They get assigned shared linkage since they are potentially not unique. rdar://26563441 (cherry picked from commit 3d34fb3b0791e790086e3ac44799324189fe525a) --- lib/IRGen/GenDecl.cpp | 3 ++- test/IRGen/Inputs/usr/include/NSOption.h | 7 +++++++ test/IRGen/objc_shared_imported_decl.sil | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/IRGen/Inputs/usr/include/NSOption.h create mode 100644 test/IRGen/objc_shared_imported_decl.sil diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 13514b9141d46..fd06a97813158 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -1416,7 +1416,8 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage, case SILLinkage::Shared: case SILLinkage::SharedExternal: - return RESULT(LinkOnceODR, Hidden, Default); + return isDefinition ? RESULT(LinkOnceODR, Hidden, Default) + : RESULT(External, Hidden, Default); case SILLinkage::Hidden: return RESULT(External, Hidden, Default); diff --git a/test/IRGen/Inputs/usr/include/NSOption.h b/test/IRGen/Inputs/usr/include/NSOption.h new file mode 100644 index 0000000000000..aec80450ef0e3 --- /dev/null +++ b/test/IRGen/Inputs/usr/include/NSOption.h @@ -0,0 +1,7 @@ +#define CF_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#define NS_OPTIONS(_type, _name) CF_OPTIONS(_type, _name) + +typedef NS_OPTIONS(int, SomeOptions) { + SomeOptionsFoo = 1, + SomeOptionsBar = 2, +}; diff --git a/test/IRGen/objc_shared_imported_decl.sil b/test/IRGen/objc_shared_imported_decl.sil new file mode 100644 index 0000000000000..eab941f68b2c2 --- /dev/null +++ b/test/IRGen/objc_shared_imported_decl.sil @@ -0,0 +1,16 @@ +// RUN: %target-swift-frontend -primary-file %s -import-objc-header %S/Inputs/usr/include/NSOption.h -emit-ir | %FileCheck %s + +// REQUIRES: objc_interop + +import Swift + +sil public @use_witness : $@convention(thin) () -> () { + %0 = witness_method $SomeOptions, #Equatable."=="!1 : (Self.Type) -> (Self, Self) -> Bool : $@convention(witness_method) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> Bool + %1 = tuple () + return %1: $() +} + +// We used to emit linkonce_odr llvm linkage for this declaration. +sil_witness_table shared SomeOptions : Equatable module __ObjC + +// CHECK: @_T0SC11SomeOptionsVs9EquatableSoWP = external hidden global