Skip to content

Commit e31c1cc

Browse files
committed
CustomAvailability: avoid exposing the synthesized function for dynamic availability checking as an API entry
For dynamic features defined from a header, we synthesize a pure Clang function to check whether the feature should be enabled at runtime. Swift modules don't have capability to deserialize this clang predicate function, leading to crasher as a result. This change fixes the crasher by hiding the synthesized function to be a module internal one. rdar://164410957
1 parent 6b5abb6 commit e31c1cc

File tree

4 files changed

+78
-4
lines changed

4 files changed

+78
-4
lines changed

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3183,9 +3183,7 @@ FuncDecl *SwiftDeclSynthesizer::makeAvailabilityDomainPredicate(
31833183
BuiltinIntegerType::get(1, ctx), ImporterImpl.ImportedHeaderUnit);
31843184
funcDecl->setBodySynthesizer(synthesizeAvailabilityDomainPredicateBody,
31853185
(void *)var);
3186-
funcDecl->setAccess(AccessLevel::Public);
3187-
funcDecl->addAttribute(
3188-
new (ctx) ExportAttr(ExportKind::Implementation, /*IsImplicit=*/true));
3186+
funcDecl->setAccess(AccessLevel::Internal);
31893187

31903188
ImporterImpl.availabilityDomainPredicates[var] = funcDecl;
31913189

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef __AVAILABILITY_DOMAIN_TEST_H
2+
#define __AVAILABILITY_DOMAIN_TEST_H
3+
4+
#include <availability_domain.h>
5+
6+
int dynamic_domain_pred();
7+
8+
CLANG_ENABLED_AVAILABILITY_DOMAIN(EnabledDomain);
9+
CLANG_DISABLED_AVAILABILITY_DOMAIN(DisabledDomain);
10+
CLANG_DYNAMIC_AVAILABILITY_DOMAIN(DynamicDomain, dynamic_domain_pred);
11+
12+
#define AVAIL 0
13+
#define UNAVAIL 1
14+
15+
__attribute__((availability(domain : EnabledDomain, AVAIL))) void
16+
available_in_enabled_domain(void);
17+
18+
__attribute__((availability(domain : EnabledDomain, UNAVAIL))) void
19+
unavailable_in_enabled_domain(void);
20+
21+
__attribute__((availability(domain : DisabledDomain, AVAIL))) void
22+
available_in_disabled_domain(void);
23+
24+
__attribute__((availability(domain : DisabledDomain, UNAVAIL))) void
25+
unavailable_in_disabled_domain(void);
26+
27+
__attribute__((availability(domain : DynamicDomain, AVAIL))) void
28+
available_in_dynamic_domain(void);
29+
30+
__attribute__((availability(domain : DynamicDomain, UNAVAIL))) void
31+
unavailable_in_dynamic_domain(void);
32+
33+
#endif // __AVAILABILITY_DOMAIN_TEST_H
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// REQUIRES: swift_feature_CustomAvailability
2+
// RUN: %empty-directory(%t/mod)
3+
// RUN: %target-swift-frontend -emit-module %s -o %t/mod/Foo.swiftmodule -parse-as-library -enable-library-evolution -module-name Foo -import-bridging-header %S/Inputs/AvailabilityDomains.h -enable-experimental-feature CustomAvailability -D FOO
4+
// RUN: %target-swift-frontend -emit-module %s -o %t/mod/Bar.swiftmodule -parse-as-library -enable-library-evolution -module-name Bar -import-bridging-header %S/Inputs/AvailabilityDomains.h -enable-experimental-feature CustomAvailability -I %t/mod -D BAR
5+
6+
#if FOO
7+
8+
@available(DynamicDomain)
9+
public struct X {
10+
public init() { }
11+
}
12+
13+
public struct Z {
14+
public init() {
15+
if #available(DynamicDomain) {
16+
print("#available")
17+
print(X())
18+
} else {
19+
print("#unavailable")
20+
}
21+
}
22+
}
23+
24+
#endif
25+
26+
#if BAR
27+
28+
import Foo
29+
30+
public struct Y {
31+
init() {
32+
if #available(DynamicDomain) {
33+
print("#available")
34+
print(X())
35+
print(Z())
36+
} else {
37+
print("#unavailable")
38+
print(Z())
39+
}
40+
}
41+
42+
}
43+
#endif

test/SILGen/availability_query_custom_domains_clang.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public func testIfAvailableDynamicDomain() {
101101
}
102102
// CHECK: end sil function '$s4Test28testIfAvailableDynamicDomainyyF'
103103

104-
// CHECK-LABEL: sil non_abi [serialized] [ossa] @$sSC33__swift_DynamicDomain_isAvailableBi1_yF : $@convention(thin) () -> Builtin.Int1
104+
// CHECK-LABEL: sil hidden [ossa] @$sSC33__swift_DynamicDomain_isAvailableBi1_yF : $@convention(thin) () -> Builtin.Int1
105105
// CHECK: bb0:
106106
// CHECK: [[QUERY_FUNC:%.*]] = function_ref @$sSo27__DynamicDomain_isAvailableSbyFTo : $@convention(c) () -> Bool
107107
// CHECK: [[QUERY_RESULT:%.*]] = apply [[QUERY_FUNC]]() : $@convention(c) () -> Bool

0 commit comments

Comments
 (0)