CustomAvailability: synthesized dynamic availability checking function should be private

When compiling a Swift module in incremental mode, each Swift source file is compiled into an object file
and we use linker to link them together. Because the predicate function for checking dynamic feature
availability is eagerly synthesized per compilation unit, the linker will complain about duplicated
symbols for them. Setting their visibility as private ensures that linker doesn't see them, thus addressing
the linker errors.

One workaround for this problem is to enable WMO.

rdar://164971313
This commit is contained in:
Xi Ge
2025-11-17 12:49:01 -08:00
parent c337446464
commit d144524209
6 changed files with 40 additions and 2 deletions

View File

@@ -3183,7 +3183,7 @@ FuncDecl *SwiftDeclSynthesizer::makeAvailabilityDomainPredicate(
BuiltinIntegerType::get(1, ctx), ImporterImpl.ImportedHeaderUnit);
funcDecl->setBodySynthesizer(synthesizeAvailabilityDomainPredicateBody,
(void *)var);
funcDecl->setAccess(AccessLevel::Internal);
funcDecl->setAccess(AccessLevel::Private);
ImporterImpl.availabilityDomainPredicates[var] = funcDecl;

View File

@@ -0,0 +1,5 @@
#include "AvailabilityDomains.h"
int dynamic_domain_pred() {
return 1;
}

View File

@@ -0,0 +1,15 @@
@available(DynamicDomain)
public struct X {
public init() { }
}
public struct Z {
public init() {
if #available(DynamicDomain) {
print("#available")
print(X())
} else {
print("#unavailable")
}
}
}

View File

@@ -0,0 +1,12 @@
public struct Y {
init() {
if #available(DynamicDomain) {
print("#available")
print(X())
print(Z())
} else {
print("#unavailable")
print(Z())
}
}
}

View File

@@ -0,0 +1,6 @@
// REQUIRES: swift_feature_CustomAvailability
// RUN: %empty-directory(%t)
// RUN: %target-clang -x c %S/Inputs/AvailabilityDomains.c -o %t/AvailabilityDomains.c.o -c
// RUN: %target-build-swift -emit-library %S/Inputs/custom_availability_file1.swift %S/Inputs/custom_availability_file2.swift -module-name main -enable-experimental-feature CustomAvailability -import-bridging-header %S/Inputs/AvailabilityDomains.h -Xlinker %t/AvailabilityDomains.c.o
// RUN: %target-build-swift -wmo -emit-library %S/Inputs/custom_availability_file1.swift %S/Inputs/custom_availability_file2.swift -module-name main -enable-experimental-feature CustomAvailability -import-bridging-header %S/Inputs/AvailabilityDomains.h -Xlinker %t/AvailabilityDomains.c.o

View File

@@ -101,7 +101,7 @@ public func testIfAvailableDynamicDomain() {
}
// CHECK: end sil function '$s4Test28testIfAvailableDynamicDomainyyF'
// CHECK-LABEL: sil hidden [ossa] @$sSC33__swift_DynamicDomain_isAvailableBi1_yF : $@convention(thin) () -> Builtin.Int1
// CHECK-LABEL: sil private [ossa] @$sSC33__swift_DynamicDomain_isAvailableBi1_yF : $@convention(thin) () -> Builtin.Int1
// CHECK: bb0:
// CHECK: [[QUERY_FUNC:%.*]] = function_ref @$sSo27__DynamicDomain_isAvailableSbyFTo : $@convention(c) () -> Bool
// CHECK: [[QUERY_RESULT:%.*]] = apply [[QUERY_FUNC]]() : $@convention(c) () -> Bool