Merge remote-tracking branch 'origin/main' into rebranch

This commit is contained in:
swift-ci
2025-08-26 17:19:55 -07:00
17 changed files with 588 additions and 99 deletions

View File

@@ -6989,6 +6989,17 @@ WARNING(attr_availability_expected_version_spec, none,
ERROR(attr_availability_requires_custom_availability, none,
"%0 requires '-enable-experimental-feature CustomAvailability'",
(AvailabilityDomain))
ERROR(attr_availability_domain_access, none,
"availability domain '%0' is "
"%select{private|fileprivate|internal|package|%error|%error}1 "
"and cannot be used in '%2' on "
"%select{private|fileprivate|internal|package|public|%error}3 %kind4",
(AvailabilityDomain, AccessLevel, DeclAttribute, AccessLevel,
const Decl *))
ERROR(attr_availability_domain_not_usable_from_inline, none,
"availability domain '%0' used in '%1' on %kind2 must be "
"'@usableFromInline' or public",
(AvailabilityDomain, DeclAttribute, const Decl *))
ERROR(availability_decl_unavailable, none,
"%0 is unavailable%select{ in %2|}1%select{|: %3}3",

View File

@@ -41,9 +41,7 @@ getCustomDomainKind(clang::FeatureAvailKind featureAvailKind) {
static const CustomAvailabilityDomain *
customDomainForClangDecl(ValueDecl *decl) {
auto *clangDecl = decl->getClangDecl();
ASSERT(clangDecl);
auto *varDecl = dyn_cast<clang::VarDecl>(clangDecl);
auto *varDecl = dyn_cast_or_null<clang::VarDecl>(clangDecl);
if (!varDecl)
return nullptr;

View File

@@ -16,6 +16,7 @@
//===----------------------------------------------------------------------===//
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/AvailabilityDomain.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTPrinter.h"
#include "swift/AST/Decl.h"
@@ -877,6 +878,20 @@ static void formatDiagnosticArgument(StringRef Modifier,
assert(Modifier.empty() && "Improper modifier for ValueDecl argument");
}
// Handle declarations representing an AvailabilityDomain specially.
if (auto VD = dyn_cast<ValueDecl>(D)) {
if (auto domain = AvailabilityDomain::forCustom(const_cast<ValueDecl *>(VD))) {
Out << "availability domain";
if (includeName) {
Out << " " << FormatOpts.OpeningQuotationMark;
Out << domain->getNameForDiagnostics();
Out << FormatOpts.ClosingQuotationMark;
}
break;
}
}
if (includeName) {
if (auto accessor = dyn_cast<AccessorDecl>(D)) {
// If it's an accessor, describe that and then switch to discussing its

View File

@@ -5257,6 +5257,12 @@ static bool diagnoseAvailabilityCondition(PoundAvailableInfo *info,
return true;
}
// Check the availability of the domain decl.
if (auto *domainDecl = spec.getDomain().getDecl()) {
auto where = ExportContext::forFunctionBody(DC, loc);
diagnoseDeclAvailability(domainDecl, loc, nullptr, where);
}
hasValidSpecs = true;
if (!domain.isPlatform())
allValidSpecsArePlatform = false;

View File

@@ -28,6 +28,7 @@
#include "swift/AST/Import.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/AST/TypeCheckRequests.h"
#include "swift/Basic/Assertions.h"
#include "clang/AST/DeclCXX.h"
@@ -70,10 +71,22 @@ static void forAllRequirementTypes(
using CheckTypeAccessCallback =
void(AccessScope, const TypeRepr *, DowngradeToWarning, ImportAccessLevel);
using CheckDeclAccessCallback = void(AccessScope, SourceLoc, ImportAccessLevel);
class AccessControlCheckerBase {
protected:
bool checkUsableFromInline;
bool shouldSkipChecking(const ValueDecl *decl);
/// Returns true if access checking ought to be skipped for the given
/// `AccessScope`.
bool shouldSkipAccessCheckingInContext(AccessScope contextAccessScope,
const ASTContext &ctx);
ImportAccessLevel getImportAccessForDecl(const ValueDecl *decl,
const DeclContext *useDC);
void checkTypeAccessImpl(
Type type, TypeRepr *typeRepr, AccessScope contextAccessScope,
const DeclContext *useDC, bool mayBeInferred,
@@ -102,6 +115,12 @@ protected:
});
}
void checkAvailabilityDomains(const Decl *D);
void checkDeclAccess(SourceLoc loc, const ValueDecl *decl,
AccessScope contextAccessScope, const DeclContext *useDC,
llvm::function_ref<CheckDeclAccessCallback> diagnose);
AccessControlCheckerBase(bool checkUsableFromInline)
: checkUsableFromInline(checkUsableFromInline) {}
@@ -117,10 +136,50 @@ public:
const ValueDecl *ownerDecl);
void checkGlobalActorAccess(const Decl *D);
void checkAvailabilityDomains(const Decl *D, AccessScope accessScope,
AccessLevel contextAccess);
};
} // end anonymous namespace
bool AccessControlCheckerBase::shouldSkipChecking(const ValueDecl *decl) {
if (!checkUsableFromInline)
return false;
if (decl->getFormalAccess() != AccessLevel::Internal &&
decl->getFormalAccess() != AccessLevel::Package)
return true;
return !decl->isUsableFromInline();
}
bool AccessControlCheckerBase::shouldSkipAccessCheckingInContext(
AccessScope contextAccessScope, const ASTContext &ctx) {
if (ctx.isAccessControlDisabled())
return true;
// Don't spend time checking local declarations; this is always valid by the
// time we get to this point.
if (contextAccessScope.isInContext() &&
contextAccessScope.getDeclContext()->isLocalContext())
return true;
return false;
}
ImportAccessLevel
AccessControlCheckerBase::getImportAccessForDecl(const ValueDecl *decl,
const DeclContext *useDC) {
auto complainImport = decl->getImportAccessFrom(useDC);
// Don't complain about an import that doesn't restrict the access
// level of the decl. This can happen with imported `package` decls.
if (complainImport && complainImport->accessLevel >= decl->getFormalAccess())
return std::nullopt;
return complainImport;
}
/// Searches the given type representation for a `DeclRefTypeRepr` that is
/// bound to a type declaration with the given access scope. The type
/// representation is searched in source order. For example, nodes in
@@ -201,12 +260,7 @@ void AccessControlCheckerBase::checkTypeAccessImpl(
llvm::function_ref<CheckTypeAccessCallback> diagnose) {
auto &Context = useDC->getASTContext();
if (Context.isAccessControlDisabled())
return;
// Don't spend time checking local declarations; this is always valid by the
// time we get to this point.
if (contextAccessScope.isInContext() &&
contextAccessScope.getDeclContext()->isLocalContext())
if (shouldSkipAccessCheckingInContext(contextAccessScope, Context))
return;
// Report where it was imported from.
@@ -229,7 +283,7 @@ void AccessControlCheckerBase::checkTypeAccessImpl(
return TypeWalker::Action::Continue;
}));
}
};
}
AccessScope problematicAccessScope = AccessScope::getPublic();
@@ -307,19 +361,36 @@ void AccessControlCheckerBase::checkTypeAccessImpl(
const ValueDecl *VD = complainRepr->getBoundDecl();
assert(VD &&
"findTypeDeclWithAccessScope should return bound TypeReprs only");
complainImport = VD->getImportAccessFrom(useDC);
// Don't complain about an import that doesn't restrict the access
// level of the decl. This can happen with imported `package` decls.
if (complainImport.has_value() &&
complainImport->accessLevel >= VD->getFormalAccess())
complainImport = std::nullopt;
complainImport = getImportAccessForDecl(VD, useDC);
}
diagnose(problematicAccessScope, complainRepr, downgradeToWarning,
complainImport);
}
void AccessControlCheckerBase::checkDeclAccess(
SourceLoc loc, const ValueDecl *decl, AccessScope contextAccessScope,
const DeclContext *useDC,
llvm::function_ref<CheckDeclAccessCallback> diagnose) {
auto &ctx = useDC->getASTContext();
if (shouldSkipAccessCheckingInContext(contextAccessScope, ctx))
return;
recordRequiredImportAccessLevelForDecl(
decl, useDC, contextAccessScope.accessLevelForDiagnostics(), loc);
AccessScope declAccessScope =
decl->getFormalAccessScope(useDC, checkUsableFromInline);
if (contextAccessScope.hasEqualDeclContextWith(declAccessScope) ||
contextAccessScope.isChildOf(declAccessScope))
return;
// The reference to the decl violates the rules of access control.
ImportAccessLevel complainImport = getImportAccessForDecl(decl, useDC);
diagnose(declAccessScope, loc, complainImport);
}
/// Checks if the access scope of the type described by \p TL is valid for the
/// type to be the type of \p context. If it isn't, calls \p diagnose with a
/// TypeRepr representing the offending part of \p TL.
@@ -556,6 +627,50 @@ void AccessControlCheckerBase::checkGlobalActorAccess(const Decl *D) {
});
}
void AccessControlCheckerBase::checkAvailabilityDomains(
const Decl *D, AccessScope accessScope, AccessLevel contextAccess) {
auto &ctx = D->getASTContext();
for (auto attr : D->getSemanticAvailableAttrs()) {
if (auto *domainDecl = attr.getDomain().getDecl()) {
checkDeclAccess(
attr.getParsedAttr()->getDomainLoc(), domainDecl, accessScope,
D->getDeclContext(),
[&](AccessScope domainAccessScope, SourceLoc useLoc,
ImportAccessLevel importLimit) {
// FIXME: [availability] Improve diagnostics by indicating the decl
// that the formal access is implied by. Enum cases, associated
// types, protocol requirements, etc. inherit their access level
// from their context.
if (checkUsableFromInline) {
ctx.Diags.diagnose(
useLoc, diag::attr_availability_domain_not_usable_from_inline,
attr.getDomain(), attr.getParsedAttr(), D);
noteLimitingImport(nullptr, ctx, importLimit, domainDecl);
return;
}
ctx.Diags.diagnose(useLoc, diag::attr_availability_domain_access,
attr.getDomain(),
domainAccessScope.accessLevelForDiagnostics(),
attr.getParsedAttr(), contextAccess, D);
noteLimitingImport(nullptr, ctx, importLimit, domainDecl);
});
}
}
}
void AccessControlCheckerBase::checkAvailabilityDomains(const Decl *D) {
auto VD = dyn_cast<ValueDecl>(D->getAbstractSyntaxDeclForAttributes());
if (!VD || shouldSkipChecking(VD))
return;
AccessScope contextAccessScope =
VD->getFormalAccessScope(VD->getDeclContext(), checkUsableFromInline);
checkAvailabilityDomains(VD, contextAccessScope, VD->getFormalAccess());
}
namespace {
class AccessControlChecker : public AccessControlCheckerBase,
public DeclVisitor<AccessControlChecker> {
@@ -573,7 +688,7 @@ public:
DeclVisitor<AccessControlChecker>::visit(D);
checkGlobalActorAccess(D);
checkAttachedMacrosAccess(D);
checkAvailabilityDomains(D);
}
// Force all kinds to be handled at a lower level.
@@ -1314,19 +1429,6 @@ public:
noteLimitingImport(MD, minImportLimit, complainRepr);
}
}
void checkAttachedMacrosAccess(const Decl *D) {
for (auto customAttrC : D->getExpandedAttrs().getAttributes<CustomAttr>()) {
auto customAttr = const_cast<CustomAttr *>(customAttrC);
auto *macroDecl = D->getResolvedMacro(customAttr);
if (macroDecl) {
diagnoseDeclAvailability(
macroDecl, customAttr->getTypeRepr()->getSourceRange(), nullptr,
ExportContext::forDeclSignature(const_cast<Decl *>(D)),
std::nullopt);
}
}
}
};
class UsableFromInlineChecker : public AccessControlCheckerBase,
@@ -1335,13 +1437,6 @@ public:
UsableFromInlineChecker()
: AccessControlCheckerBase(/*checkUsableFromInline=*/true) {}
static bool shouldSkipChecking(const ValueDecl *VD) {
if (VD->getFormalAccess() != AccessLevel::Internal &&
VD->getFormalAccess() != AccessLevel::Package)
return true;
return !VD->isUsableFromInline();
};
void visit(Decl *D) {
if (!D->getASTContext().isSwiftVersionAtLeast(4, 2))
return;
@@ -1355,6 +1450,7 @@ public:
DeclVisitor<UsableFromInlineChecker>::visit(D);
checkGlobalActorAccess(D);
checkAvailabilityDomains(D);
}
// Force all kinds to be handled at a lower level.
@@ -2141,9 +2237,34 @@ public:
checkType(customAttr->getType(), customAttr->getTypeRepr(), D);
}
void checkAttachedMacros(const Decl *D) {
for (auto customAttrC : D->getExpandedAttrs().getAttributes<CustomAttr>()) {
auto customAttr = const_cast<CustomAttr *>(customAttrC);
auto *macroDecl = D->getResolvedMacro(customAttr);
if (macroDecl) {
diagnoseDeclAvailability(macroDecl,
customAttr->getTypeRepr()->getSourceRange(),
nullptr, Where, std::nullopt);
}
}
}
void checkAvailabilityDomains(const Decl *D) {
D = D->getAbstractSyntaxDeclForAttributes();
for (auto attr : D->getSemanticAvailableAttrs()) {
if (auto *domainDecl = attr.getDomain().getDecl()) {
diagnoseDeclAvailability(domainDecl,
attr.getParsedAttr()->getDomainLoc(), nullptr,
Where, std::nullopt);
}
}
}
void visit(Decl *D) {
DeclVisitor<DeclAvailabilityChecker>::visit(D);
checkGlobalActor(D);
checkAttachedMacros(D);
checkAvailabilityDomains(D);
}
// Force all kinds to be handled at a lower level.
@@ -2373,14 +2494,10 @@ public:
}
void checkConstrainedExtensionRequirements(ExtensionDecl *ED,
bool hasExportedMembers) {
ExportabilityReason reason) {
if (!ED->getTrailingWhereClause())
return;
ExportabilityReason reason =
hasExportedMembers ? ExportabilityReason::ExtensionWithPublicMembers
: ExportabilityReason::ExtensionWithConditionalConformances;
forAllRequirementTypes(ED, [&](Type type, TypeRepr *typeRepr) {
checkType(type, typeRepr, ED, reason,
DeclAvailabilityFlag::DisableUnsafeChecking);
@@ -2424,7 +2541,23 @@ public:
// the 'where' clause must only name exported types.
Where = wasWhere.withExported(hasExportedMembers ||
!ED->getInherited().empty());
checkConstrainedExtensionRequirements(ED, hasExportedMembers);
ExportabilityReason reason =
hasExportedMembers
? ExportabilityReason::ExtensionWithPublicMembers
: ExportabilityReason::ExtensionWithConditionalConformances;
checkConstrainedExtensionRequirements(ED, reason);
// Diagnose the exportability of the availability domains referenced by the
// @available attributes attached to the extension.
if (Where.isExported()) {
for (auto availableAttr : ED->getSemanticAvailableAttrs()) {
if (auto *domainDecl = availableAttr.getDomain().getDecl()) {
TypeChecker::diagnoseDeclRefExportability(
availableAttr.getParsedAttr()->getDomainLoc(), domainDecl,
Where.withReason(reason));
}
}
}
// If we haven't already visited the extended nominal visit it here.
// This logic is too wide but prevents false reports of an unused public
@@ -2492,7 +2625,7 @@ public:
} // end anonymous namespace
static void checkExtensionGenericParamAccess(const ExtensionDecl *ED) {
static void checkExtensionAccess(const ExtensionDecl *ED) {
auto *AA = ED->getAttrs().getAttribute<AccessControlAttr>();
if (!AA)
return;
@@ -2523,8 +2656,11 @@ static void checkExtensionGenericParamAccess(const ExtensionDecl *ED) {
break;
}
AccessControlChecker().checkGenericParamAccess(
ED, ED, desiredAccessScope, userSpecifiedAccess);
auto accessChecker = AccessControlChecker();
accessChecker.checkGenericParamAccess(ED, ED, desiredAccessScope,
userSpecifiedAccess);
accessChecker.checkAvailabilityDomains(ED, desiredAccessScope,
userSpecifiedAccess);
}
DisallowedOriginKind swift::getDisallowedOriginKind(const Decl *decl,
@@ -2660,13 +2796,10 @@ void swift::checkAccessControl(Decl *D) {
AccessControlChecker(allowInlineable).visit(D);
UsableFromInlineChecker().visit(D);
} else if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
checkExtensionGenericParamAccess(ED);
checkExtensionAccess(ED);
registerPackageAccessForPackageExtendedType(ED);
}
if (isa<AccessorDecl>(D))
return;
auto where = ExportContext::forDeclSignature(D);
if (where.isImplicit())
return;

View File

@@ -563,6 +563,9 @@ void AttributeChecker::visitSensitiveAttr(SensitiveAttr *attr) {
}
void AttributeChecker::visitTransparentAttr(TransparentAttr *attr) {
if (attr->isImplicit())
return;
DeclContext *dc = D->getDeclContext();
// Protocol declarations cannot be transparent.
if (isa<ProtocolDecl>(dc))

View File

@@ -3719,11 +3719,11 @@ public:
TypeChecker::checkProtocolSelfRequirements(FD);
}
checkAccessControl(FD);
TypeChecker::checkParameterList(FD->getParameters(), FD);
}
checkAccessControl(FD);
TypeChecker::checkDeclAttributes(FD);
TypeChecker::checkDistributedFunc(FD);

View File

@@ -12,7 +12,7 @@
/// A type whose metatype can be shared across arbitrary concurrent contexts
/// without introducing a risk of data races. When a generic type `T` conforms
/// to `SendableMetatype`, its metatype `T.Type` conforms to `Sendable`. All
/// to `SendableMetatype`, its metatype `T.Type` conforms to `Sendable`. All
/// concrete types implicitly conform to the `SendableMetatype` protocol, so its
/// primary purpose is in generic code to prohibit the use of isolated
/// conformances along with the generic type.
@@ -35,7 +35,7 @@
///
/// @MainActor
/// class MyModel: @MainActor P {
/// /*implicitly @MainActor/*
/// /* implicitly @MainActor */
/// static func f() {
/// /* on the main actor */
/// }

View File

@@ -1,11 +1,7 @@
#include <feature-availability.h>
#include <availability_domain.h>
static struct __AvailabilityDomain bay_bridge
__attribute__((availability_domain(BayBridge))) = {
__AVAILABILITY_DOMAIN_ENABLED, 0};
static struct __AvailabilityDomain golden_gate_bridge
__attribute__((availability_domain(GoldenGateBridge))) = {
__AVAILABILITY_DOMAIN_DISABLED, 0};
CLANG_DISABLED_AVAILABILITY_DOMAIN(BayBridge);
CLANG_DISABLED_AVAILABILITY_DOMAIN(GoldenGateBridge);
#define AVAIL 0
#define UNAVAIL 1

View File

@@ -0,0 +1,328 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify \
// RUN: -import-objc-header %S/Inputs/availability_domains_bridging_header.h \
// RUN: -I %S/../Inputs/custom-modules/availability-domains \
// RUN: -enable-experimental-feature CustomAvailability \
// RUN: -experimental-spi-only-imports -parse-as-library -swift-version 4 \
// RUN: %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify \
// RUN: -import-objc-header %S/Inputs/availability_domains_bridging_header.h \
// RUN: -I %S/../Inputs/custom-modules/availability-domains \
// RUN: -enable-experimental-feature CustomAvailability \
// RUN: -experimental-spi-only-imports -parse-as-library -swift-version 5 \
// RUN: %s -verify-additional-prefix swift5-
// REQUIRES: swift_feature_CustomAvailability
private import Rivers // also re-exported by Oceans
internal import Oceans
// expected-note@-1 22 {{availability domain 'Arctic' imported as 'internal' from 'Oceans' here}}
// expected-swift5-note@-2 2 {{availability domain 'Arctic' imported as 'internal' from 'Oceans' here}}
// expected-note@-3 23 {{availability domain 'Colorado' imported as 'internal' from 'Oceans' here}}
// expected-swift5-note@-4 2 {{availability domain 'Colorado' imported as 'internal' from 'Oceans' here}}
// expected-note@-5 22 {{availability domain 'Grand' imported as 'internal' from 'Oceans' here}}
// expected-swift5-note@-6 2 {{availability domain 'Grand' imported as 'internal' from 'Oceans' here}}
public import Seas
@_spiOnly import Lakes
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public global function 'publicFunc()'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public global function 'publicFunc()'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public global function 'publicFunc()'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public func publicFunc() { }
@available(Colorado) // expected-swift5-error {{availability domain 'Colorado' used in '@available' on global function 'usableFromInlineFunc()' must be '@usableFromInline' or public}}
@available(Grand) // expected-swift5-error {{availability domain 'Grand' used in '@available' on global function 'usableFromInlineFunc()' must be '@usableFromInline' or public}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-swift5-error {{availability domain 'Arctic' used in '@available' on global function 'usableFromInlineFunc()' must be '@usableFromInline' or public}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
@usableFromInline func usableFromInlineFunc() { }
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public global function 'spiFunc()'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public global function 'spiFunc()'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public global function 'spiFunc()'}}
@available(Baltic)
@available(BayBridge)
@available(Salt)
@_spi(Private) public func spiFunc() { }
@available(Colorado)
@available(Grand) // expected-warning {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic)
@available(Baltic)
@available(BayBridge)
@available(Salt)
func internalFunc() { }
@available(Colorado)
@available(Grand) // expected-warning {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic)
@available(Baltic)
@available(BayBridge)
@available(Salt)
private func privateFunc() { }
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public var 'publicGlobalVar'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public var 'publicGlobalVar'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public var 'publicGlobalVar'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public var publicGlobalVar: Int {
get { 0 }
set { }
}
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public struct 'PublicStruct'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public struct 'PublicStruct'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public struct 'PublicStruct'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public struct PublicStruct { }
public struct PublicGenericStruct<T> {
var value: T
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public initializer 'init(value:)'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public initializer 'init(value:)'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public initializer 'init(value:)'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public init(value: T) {
self.value = value
}
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public property 'publicProperty'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public property 'publicProperty'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public property 'publicProperty'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public var publicProperty: T { value }
@available(Colorado) // expected-swift5-error {{availability domain 'Colorado' used in '@available' on property 'usableFromInlineProperty' must be '@usableFromInline' or public}}
@available(Grand) // expected-swift5-error {{availability domain 'Grand' used in '@available' on property 'usableFromInlineProperty' must be '@usableFromInline' or public}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-swift5-error {{availability domain 'Arctic' used in '@available' on property 'usableFromInlineProperty' must be '@usableFromInline' or public}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
@usableFromInline var usableFromInlineProperty: T { value }
public var publicPropertyWithSetter: T {
get { value }
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public setter for property 'publicPropertyWithSetter'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public setter for property 'publicPropertyWithSetter'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public setter for property 'publicPropertyWithSetter'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
set { value = newValue }
}
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public instance method 'publicMethod()'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public instance method 'publicMethod()'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public instance method 'publicMethod()'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public func publicMethod() { }
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public subscript 'subscript(_:)'}}
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public subscript 'subscript(_:)'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public subscript 'subscript(_:)'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public subscript 'subscript(_:)'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public subscript(indexForSubscriptInColorado: T) -> T { value }
}
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public enum 'PublicEnum'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public enum 'PublicEnum'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public enum 'PublicEnum'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public enum PublicEnum { }
public enum PublicEnumWithCase {
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public enum case 'colorado'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public enum case 'colorado'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public enum case 'colorado'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
case colorado
}
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public class 'PublicClass'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public class 'PublicClass'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public class 'PublicClass'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public class PublicClass { }
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public protocol 'PublicProtocol'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public protocol 'PublicProtocol'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public protocol 'PublicProtocol'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public protocol PublicProtocol { }
public protocol PublicProtocolWithAssociatedType {
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public associated type 'AssociatedType'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public associated type 'AssociatedType'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public associated type 'AssociatedType'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
associatedtype AssociatedType
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public instance method 'requirement()'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public instance method 'requirement()'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public instance method 'requirement()'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
func requirement() -> AssociatedType
}
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public type alias 'PublicTypealias'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public type alias 'PublicTypealias'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public type alias 'PublicTypealias'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
public typealias PublicTypealias = Int
@available(Colorado)
@available(Grand) // expected-warning {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic)
@available(Baltic)
@available(BayBridge)
@available(Salt)
extension PublicGenericStruct { }
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be used in '@available' on public extension of generic struct 'PublicGenericStruct'}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be used in '@available' on public extension of generic struct 'PublicGenericStruct'}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be used in '@available' on public extension of generic struct 'PublicGenericStruct'}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // FIXME: Should be diangosed
public extension PublicGenericStruct { }
@available(Colorado)
@available(Grand) // expected-warning {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic)
@available(Baltic)
@available(BayBridge)
@available(Salt)
extension PublicGenericStruct {
func internalMethodInExtensionInColorado() { }
}
@available(Colorado) // expected-error {{cannot use availability domain 'Colorado' in an extension with public or '@usableFromInline' members; 'Rivers' was not imported publicly}}
@available(Grand) // expected-error {{cannot use availability domain 'Grand' in an extension with public or '@usableFromInline' members; 'Rivers' was not imported publicly}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{cannot use availability domain 'Arctic' in an extension with public or '@usableFromInline' members; 'Oceans' was not imported publicly}}
@available(Baltic)
@available(BayBridge)
// FIXME: Duplicate error
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
// expected-error@-1 {{cannot use availability domain 'Salt' in an extension with public or '@usableFromInline' members; 'Lakes' was imported for SPI only}}
extension PublicGenericStruct {
public func publicMethodInExtensionInColorado() { }
}
@available(Colorado)
@available(Grand) // expected-warning {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic)
@available(Baltic)
@available(BayBridge)
@available(Salt)
extension PublicGenericStruct where T: PublicProtocolWithAssociatedType { }
@available(Colorado) // expected-error {{cannot use availability domain 'Colorado' in an extension with conditional conformances; 'Rivers' was not imported publicly}}
@available(Grand) // expected-error {{cannot use availability domain 'Grand' in an extension with conditional conformances; 'Rivers' was not imported publicly}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{cannot use availability domain 'Arctic' in an extension with conditional conformances; 'Oceans' was not imported publicly}}
@available(Baltic)
@available(BayBridge)
// FIXME: Duplicate error
@available(Salt) // expected-error {{cannot use availability domain 'Salt' in an extension with conditional conformances; 'Lakes' was imported for SPI only}}
// expected-error@-1 {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
extension PublicGenericStruct: PublicProtocol {}
@available(Colorado) // expected-error {{cannot use availability domain 'Colorado' in an extension with public or '@usableFromInline' members; 'Rivers' was not imported publicly}}
@available(Grand) // expected-error {{cannot use availability domain 'Grand' in an extension with public or '@usableFromInline' members; 'Rivers' was not imported publicly}}
// expected-warning@-1 {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic) // expected-error {{cannot use availability domain 'Arctic' in an extension with public or '@usableFromInline' members; 'Oceans' was not imported publicly}}
@available(Baltic)
@available(BayBridge)
// FIXME: Duplicate error
@available(Salt) // expected-error {{cannot use availability domain 'Salt' here; 'Lakes' was imported for SPI only}}
// expected-error@-1 {{cannot use availability domain 'Salt' in an extension with public or '@usableFromInline' members; 'Lakes' was imported for SPI only}}
extension PublicGenericStruct: PublicProtocolWithAssociatedType {
public func requirement() -> Int { 0 }
}
@inlinable public func inlinableFunc() {
if #available(Colorado) { } // expected-error {{availability domain 'Colorado' is internal and cannot be referenced from an '@inlinable' function}}
if #available(Grand) { } // expected-error {{availability domain 'Grand' is internal and cannot be referenced from an '@inlinable' function}}
if #available(Arctic) { } // expected-error {{availability domain 'Arctic' is internal and cannot be referenced from an '@inlinable' function}}
if #available(Baltic) { }
if #available(BayBridge) { }
if #available(Salt) { } // expected-error {{availability domain 'Salt' cannot be used in an '@inlinable' function because 'Lakes' was imported for SPI only}}
@available(Colorado) // expected-error {{availability domain 'Colorado' is internal and cannot be referenced from an '@inlinable' function}}
@available(Grand) // expected-error {{availability domain 'Grand' is internal and cannot be referenced from an '@inlinable' function}}
@available(Arctic) // expected-error {{availability domain 'Arctic' is internal and cannot be referenced from an '@inlinable' function}}
@available(Baltic)
@available(BayBridge)
@available(Salt) // expected-error {{availability domain 'Salt' cannot be used in an '@inlinable' function because 'Lakes' was imported for SPI only}}
func nestedFunc() { }
}
public func nonInlinablePublicFunc() {
if #available(Colorado) { }
if #available(Grand) { } // expected-warning {{availability domain 'Grand' is deprecated: Use Colorado instead}}
if #available(Arctic) { }
if #available(Baltic) { }
if #available(BayBridge) { }
if #available(Salt) { }
@available(Colorado)
@available(Grand) // expected-warning {{availability domain 'Grand' is deprecated: Use Colorado instead}}
@available(Arctic)
@available(Baltic)
@available(BayBridge)
@available(Salt)
func nestedFunc() { }
}

View File

@@ -1,16 +1,10 @@
#include <feature-availability.h>
static struct __AvailabilityDomain __EnabledDomain __attribute__((
availability_domain(EnabledDomain))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
static struct __AvailabilityDomain __DisabledDomain __attribute__((
availability_domain(DisabledDomain))) = {__AVAILABILITY_DOMAIN_DISABLED, 0};
#include <availability_domain.h>
int dynamic_domain_pred();
static struct __AvailabilityDomain __DynamicDomain
__attribute__((availability_domain(DynamicDomain))) = {
__AVAILABILITY_DOMAIN_DYNAMIC, dynamic_domain_pred};
CLANG_ENABLED_AVAILABILITY_DOMAIN(EnabledDomain);
CLANG_DISABLED_AVAILABILITY_DOMAIN(DisabledDomain);
CLANG_DYNAMIC_AVAILABILITY_DOMAIN(DynamicDomain, dynamic_domain_pred);
#define AVAIL 0
#define UNAVAIL 1

View File

@@ -0,0 +1,12 @@
#include <availability_domain.h>
CLANG_ENABLED_AVAILABILITY_DOMAIN(Salt);
#define AVAIL 0
#define UNAVAIL 1
__attribute__((availability(domain:Salt, AVAIL)))
void available_in_salt(void);
#undef UNAVAIL
#undef AVAIL

View File

@@ -1,15 +1,11 @@
#include <Rivers.h>
#include <feature-availability.h>
#include <availability_domain.h>
int arctic_pred(void);
int pacific_pred(void);
static struct __AvailabilityDomain arctic_domain
__attribute__((availability_domain(Arctic))) = {
__AVAILABILITY_DOMAIN_DYNAMIC, arctic_pred};
static struct __AvailabilityDomain pacific_domain
__attribute__((availability_domain(Pacific))) = {
__AVAILABILITY_DOMAIN_DYNAMIC, pacific_pred};
CLANG_DYNAMIC_AVAILABILITY_DOMAIN(Arctic, arctic_pred);
CLANG_DYNAMIC_AVAILABILITY_DOMAIN(Pacific, pacific_pred);
#define AVAIL 0
#define UNAVAIL 1

View File

@@ -1,7 +1,9 @@
#include <feature-availability.h>
#include <availability_domain.h>
static struct __AvailabilityDomain colorado_domain __attribute__((
availability_domain(Colorado))) = {__AVAILABILITY_DOMAIN_DISABLED, 0};
CLANG_DISABLED_AVAILABILITY_DOMAIN(Colorado);
__attribute__((deprecated("Use Colorado instead")))
CLANG_DISABLED_AVAILABILITY_DOMAIN(Grand);
#define AVAIL 0
#define UNAVAIL 1

View File

@@ -1,9 +1,7 @@
#include <feature-availability.h>
#include <availability_domain.h>
static struct __AvailabilityDomain baltic_domain __attribute__((
availability_domain(Baltic))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
static struct __AvailabilityDomain _mediterranean __attribute__((
availability_domain(Mediterranean))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
CLANG_ENABLED_AVAILABILITY_DOMAIN(Baltic);
CLANG_DISABLED_AVAILABILITY_DOMAIN(Mediterranean);
#define AVAIL 0
#define UNAVAIL 1

View File

@@ -12,3 +12,8 @@ module Seas {
header "Seas.h"
export *
}
module Lakes {
header "Lakes.h"
export *
}

View File

@@ -1,18 +1,10 @@
#include <feature-availability.h>
static struct __AvailabilityDomain __EnabledDomain
__attribute__((availability_domain(EnabledDomain))) = {
__AVAILABILITY_DOMAIN_ENABLED, 0};
static struct __AvailabilityDomain __DisabledDomain
__attribute__((availability_domain(DisabledDomain))) = {
__AVAILABILITY_DOMAIN_DISABLED, 0};
#include <availability_domain.h>
int dynamic_domain_pred();
static struct __AvailabilityDomain __DynamicDomain
__attribute__((availability_domain(DynamicDomain))) = {
__AVAILABILITY_DOMAIN_DYNAMIC, dynamic_domain_pred};
CLANG_ENABLED_AVAILABILITY_DOMAIN(EnabledDomain);
CLANG_DISABLED_AVAILABILITY_DOMAIN(DisabledDomain);
CLANG_DYNAMIC_AVAILABILITY_DOMAIN(DynamicDomain, dynamic_domain_pred);
#define AVAIL 0
#define UNAVAIL 1