diff --git a/benchmark/single-source/SetTests.swift b/benchmark/single-source/SetTests.swift index e3aff23ac9cd4..b23cd3ddcc2ec 100644 --- a/benchmark/single-source/SetTests.swift +++ b/benchmark/single-source/SetTests.swift @@ -25,11 +25,13 @@ let setAB = Set(0 ..< size) // 0 ..< 400 let setCD = Set(size ..< 2 * size) // 400 ..< 800 let setBC = Set(size - quarter ..< 2 * size - quarter) // 300 ..< 700 let setB = Set(size - quarter ..< size) // 300 ..< 400 +let setCDS = Set(size ..< (size + (size/4))) // 400 ..< 500 let setOAB = Set(setAB.map(Box.init)) let setOCD = Set(setCD.map(Box.init)) let setOBC = Set(setBC.map(Box.init)) let setOB = Set(setB.map(Box.init)) +let setOCDS = Set(setCDS.map(Box.init)) let countA = size - quarter // 300 let countB = quarter // 100 @@ -368,6 +370,16 @@ public let SetTests = [ runFunction: { n in run_SetIsDisjointBox(setOAB, setOCD, true, 50 * n) }, tags: [.validation, .api, .Set], setUpFunction: { blackHole([setOAB, setOCD]) }), + BenchmarkInfo( + name: "Set.isDisjoint.Smaller.Int0", + runFunction: { n in run_SetIsDisjointIntCommutative(setAB, setCDS, true, 50 * n) }, + tags: [.validation, .api, .Set], + setUpFunction: { blackHole([setAB, setCDS]) }), + BenchmarkInfo( + name: "Set.isDisjoint.Smaller.Box0", + runFunction: { n in run_SetIsDisjointBoxCommutative(setOAB, setOCDS, true, 50 * n) }, + tags: [.validation, .api, .Set], + setUpFunction: { blackHole([setOAB, setOCDS]) }), BenchmarkInfo( name: "Set.isDisjoint.Int25", runFunction: { n in run_SetIsDisjointInt(setB, setAB, false, 5000 * n) }, @@ -891,6 +903,22 @@ public func run_SetIsDisjointInt( } } +// Run isDisjoint Int switching the order of the two sets. +@inline(never) +public func run_SetIsDisjointIntCommutative( + _ a: Set, + _ b: Set, + _ r: Bool, + _ n: Int) { + for _ in 0 ..< n { + let isDisjointA = a.isDisjoint(with: identity(b)) + CheckResults(isDisjointA == r) + + let isDisjointB = b.isDisjoint(with: identity(a)) + CheckResults(isDisjointB == r) + } +} + @inline(never) public func run_SetIsDisjointSeqInt( _ a: Set, @@ -1091,6 +1119,22 @@ func run_SetIsDisjointBox( } } +// Run isDisjoint Box switching the order of the two sets. +@inline(never) +func run_SetIsDisjointBoxCommutative( + _ a: Set>, + _ b: Set>, + _ r: Bool, + _ n: Int) { + for _ in 0 ..< n { + let isDisjointA = a.isDisjoint(with: identity(b)) + CheckResults(isDisjointA == r) + + let isDisjointB = b.isDisjoint(with: identity(a)) + CheckResults(isDisjointB == r) + } +} + @inline(never) func run_SetIsDisjointSeqBox( _ a: Set>, diff --git a/cmake/modules/Libdispatch.cmake b/cmake/modules/Libdispatch.cmake index 8791ea888ecfa..013ffcb593b9a 100644 --- a/cmake/modules/Libdispatch.cmake +++ b/cmake/modules/Libdispatch.cmake @@ -47,7 +47,8 @@ endif() # Build any target libdispatch if needed. foreach(sdk ${SWIFT_SDKS}) # Darwin targets have libdispatch available, do not build it. - if(NOT "${sdk}" IN_LIST SWIFT_DARWIN_PLATFORMS) + # Wasm/WASI doesn't support libdispatch yet. See https://bugs.swift.org/browse/SR-12097 for more details. + if(NOT "${sdk}" IN_LIST SWIFT_DARWIN_PLATFORMS AND NOT "${sdk}" STREQUAL WASI) list(APPEND DISPATCH_SDKS "${sdk}") endif() endforeach() diff --git a/docs/HowToGuides/GettingStarted.md b/docs/HowToGuides/GettingStarted.md index fa1a2137d3a92..1bbed24c00db4 100644 --- a/docs/HowToGuides/GettingStarted.md +++ b/docs/HowToGuides/GettingStarted.md @@ -16,7 +16,7 @@ toolchain as a one-off, there are a couple of differences: - [Troubleshooting cloning issues](#troubleshooting-cloning-issues) - [Installing dependencies](#installing-dependencies) - [macOS](#macOS) - - [Ubuntu Linux](#ubuntu-linux) + - [Linux](#linux) - [Building the project for the first time](#building-the-project-for-the-first-time) - [Spot check dependencies](#spot-check-dependencies) - [The roles of different tools](#the-roles-of-different-tools) diff --git a/docs/SIL.rst b/docs/SIL.rst index fa81b764c7ebe..9c3c8961c1a79 100644 --- a/docs/SIL.rst +++ b/docs/SIL.rst @@ -3079,7 +3079,7 @@ alloc_stack ``````````` :: - sil-instruction ::= 'alloc_stack' '[dynamic_lifetime]'? sil-type (',' debug-var-attr)* + sil-instruction ::= 'alloc_stack' '[dynamic_lifetime]'? '[lexical]'? sil-type (',' debug-var-attr)* %1 = alloc_stack $T // %1 has type $*T @@ -3102,6 +3102,9 @@ The ``dynamic_lifetime`` attribute specifies that the initialization and destruction of the stored value cannot be verified at compile time. This is the case, e.g. for conditionally initialized objects. +The optional ``lexical`` attribute specifies that the operand corresponds to a +local variable in the Swift source. + The memory is not retainable. To allocate a retainable box for a value type, use ``alloc_box``. diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 5227dfa4e7c46..b3b32591277a5 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -782,6 +782,9 @@ ERROR(serialization_name_mismatch_repl,none, ERROR(serialization_target_incompatible,Fatal, "module %0 was created for incompatible target %1: %2", (Identifier, StringRef, StringRef)) +ERROR(serialization_sdk_mismatch,Fatal, + "cannot load module %0 built with SDK '%1' when using SDK '%2': %3", + (Identifier, StringRef, StringRef, StringRef)) ERROR(serialization_target_incompatible_repl,none, "module %0 was created for incompatible target %1: %2", (Identifier, StringRef, StringRef)) diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 427bc6e28fecf..9f51d44d38d20 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -81,6 +81,12 @@ enum class IRGenEmbedMode : unsigned { EmbedBitcode }; +enum class SwiftAsyncFramePointerKind : unsigned { + Auto, // Choose Swift async extended frame info based on deployment target. + Always, // Unconditionally emit Swift async extended frame info. + Never, // Don't emit Swift async extended frame info. +}; + using clang::PointerAuthSchema; struct PointerAuthOptions : clang::PointerAuthOptions { @@ -282,6 +288,8 @@ class IRGenOptions { IRGenLLVMLTOKind LLVMLTOKind : 2; + SwiftAsyncFramePointerKind SwiftAsyncFramePointer : 2; + /// Add names to LLVM values. unsigned HasValueNamesSetting : 1; unsigned ValueNames : 1; @@ -393,7 +401,9 @@ class IRGenOptions { Playground(false), EmitStackPromotionChecks(false), FunctionSections(false), PrintInlineTree(false), EmbedMode(IRGenEmbedMode::None), - LLVMLTOKind(IRGenLLVMLTOKind::None), HasValueNamesSetting(false), + LLVMLTOKind(IRGenLLVMLTOKind::None), + SwiftAsyncFramePointer(SwiftAsyncFramePointerKind::Always), + HasValueNamesSetting(false), ValueNames(false), EnableReflectionMetadata(true), EnableReflectionNames(true), EnableAnonymousContextMangledNames(false), ForcePublicLinkage(false), LazyInitializeClassMetadata(false), diff --git a/include/swift/AST/SearchPathOptions.h b/include/swift/AST/SearchPathOptions.h index f873e82ada368..02f61eadfe59a 100644 --- a/include/swift/AST/SearchPathOptions.h +++ b/include/swift/AST/SearchPathOptions.h @@ -82,6 +82,10 @@ class SearchPathOptions { /// would for a non-system header. bool DisableModulesValidateSystemDependencies = false; + /// Enforce loading only serialized modules built with the same SDK + /// as the context loading it. + bool EnableSameSDKCheck = true; + /// A set of compiled modules that may be ready to use. std::vector CandidateCompiledModules; diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index f8d161d346e51..816e83b2817d3 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -127,6 +127,9 @@ namespace swift { /// The target variant SDK version, if known. Optional VariantSDKVersion; + /// The SDK canonical name, if known. + std::string SDKName; + /// The alternate name to use for the entry point instead of main. std::string entryPointFunctionName = "main"; @@ -301,6 +304,9 @@ namespace swift { /// Enable experimental concurrency model. bool EnableExperimentalConcurrency = false; + /// Enable experimental support for emitting defined borrow scopes. + bool EnableExperimentalDefinedLifetimes = false; + /// Enable experimental support for named opaque result types, e.g. /// `func f() -> T`. bool EnableExperimentalNamedOpaqueTypes = false; diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 5da7cf5b6d9d8..3b36485cb2f1d 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -247,6 +247,10 @@ def enable_experimental_concurrency : Flag<["-"], "enable-experimental-concurrency">, HelpText<"Enable experimental concurrency model">; +def enable_experimental_defined_lifetimes : + Flag<["-"], "enable-experimental-defined-lifetimes">, + HelpText<"Enable experimental defined lifetimes">; + def enable_experimental_distributed : Flag<["-"], "enable-experimental-distributed">, HelpText<"Enable experimental 'distributed' actors and functions">; @@ -802,6 +806,10 @@ def type_info_dump_filter_EQ : Joined<["-"], "type-info-dump-filter=">, Flags<[FrontendOption]>, HelpText<"One of 'all', 'resilient' or 'fragile'">; +def swift_async_frame_pointer_EQ : Joined<["-"], "swift-async-frame-pointer=">, + Flags<[FrontendOption]>, + HelpText<"One of 'auto', 'always' or 'never'">; + def previous_module_installname_map_file : Separate<["-"], "previous-module-installname-map-file">, MetaVarName<"">, HelpText<"Path to a Json file indicating module name to installname map for @_originallyDefinedIn">; @@ -827,6 +835,9 @@ def target_sdk_version : Separate<["-"], "target-sdk-version">, def target_variant_sdk_version : Separate<["-"], "target-variant-sdk-version">, HelpText<"The version of target variant SDK used for compilation">; +def target_sdk_name : Separate<["-"], "target-sdk-name">, + HelpText<"Canonical name of the target SDK used for compilation">; + def extra_clang_options_only : Flag<["-"], "only-use-extra-clang-opts">, HelpText<"Options passed via -Xcc are sufficient for Clang configuration">; diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h index e49624163ce90..577c580a93026 100644 --- a/include/swift/SIL/SILBuilder.h +++ b/include/swift/SIL/SILBuilder.h @@ -381,14 +381,16 @@ class SILBuilder { AllocStackInst *createAllocStack(SILLocation Loc, SILType elementType, Optional Var = None, - bool hasDynamicLifetime = false) { + bool hasDynamicLifetime = false, + bool isLexical = false) { llvm::SmallString<4> Name; Loc.markAsPrologue(); assert((!dyn_cast_or_null(Loc.getAsASTNode()) || Var) && "location is a VarDecl, but SILDebugVariable is empty"); return insert(AllocStackInst::create( getSILDebugLocation(Loc), elementType, getFunction(), - substituteAnonymousArgs(Name, Var, Loc), hasDynamicLifetime)); + substituteAnonymousArgs(Name, Var, Loc), hasDynamicLifetime, + isLexical)); } AllocRefInst *createAllocRef(SILLocation Loc, SILType ObjectType, diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h index a05a5c5c6c074..3d8aa161249db 100644 --- a/include/swift/SIL/SILCloner.h +++ b/include/swift/SIL/SILCloner.h @@ -759,9 +759,9 @@ SILCloner::visitAllocStackInst(AllocStackInst *Inst) { Loc = MandatoryInlinedLocation::getAutoGeneratedLocation(); VarInfo = None; } - auto *NewInst = - getBuilder().createAllocStack(Loc, getOpType(Inst->getElementType()), - VarInfo, Inst->hasDynamicLifetime()); + auto *NewInst = getBuilder().createAllocStack( + Loc, getOpType(Inst->getElementType()), VarInfo, + Inst->hasDynamicLifetime(), Inst->isLexical()); remapDebugVarInfo(DebugVarCarryingInst(NewInst)); recordClonedInstruction(Inst, NewInst); } diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index f285123cf499f..a795714b11fa5 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -1900,16 +1900,16 @@ class AllocStackInst final friend SILBuilder; bool dynamicLifetime = false; + bool lexical = false; AllocStackInst(SILDebugLocation Loc, SILType elementType, - ArrayRef TypeDependentOperands, - SILFunction &F, - Optional Var, bool hasDynamicLifetime); + ArrayRef TypeDependentOperands, SILFunction &F, + Optional Var, bool hasDynamicLifetime, + bool isLexical); static AllocStackInst *create(SILDebugLocation Loc, SILType elementType, - SILFunction &F, - Optional Var, - bool hasDynamicLifetime); + SILFunction &F, Optional Var, + bool hasDynamicLifetime, bool isLexical); SIL_DEBUG_VAR_SUPPLEMENT_TRAILING_OBJS_IMPL() @@ -1940,6 +1940,9 @@ class AllocStackInst final /// is conditionally initialized. bool hasDynamicLifetime() const { return dynamicLifetime; } + /// Whether the alloc_stack instruction corresponds to a source-level VarDecl. + bool isLexical() const { return lexical; } + /// Return the debug variable information attached to this instruction. Optional getVarInfo() const { Optional AuxVarType; diff --git a/include/swift/Serialization/SerializationOptions.h b/include/swift/Serialization/SerializationOptions.h index 2b180591a19d7..8f19f7d9ed22d 100644 --- a/include/swift/Serialization/SerializationOptions.h +++ b/include/swift/Serialization/SerializationOptions.h @@ -35,6 +35,7 @@ namespace swift { bool SkipSymbolGraphInheritedDocs = true; bool IncludeSPISymbolsInSymbolGraph = false; llvm::VersionTuple UserModuleVersion; + std::string SDKName; StringRef GroupInfoPath; StringRef ImportedHeader; diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h index e5564a139473d..a2ffe970ed987 100644 --- a/include/swift/Serialization/Validation.h +++ b/include/swift/Serialization/Validation.h @@ -66,7 +66,11 @@ enum class Status { TargetIncompatible, /// The module file was built for a target newer than the current target. - TargetTooNew + TargetTooNew, + + /// The module file was built with a different SDK than the one in use + /// to build the client. + SDKMismatch }; /// Returns true if the data looks like it contains a serialized AST. @@ -80,6 +84,7 @@ struct ValidationInfo { StringRef miscVersion = {}; version::Version compatibilityVersion = {}; llvm::VersionTuple userModuleVersion; + StringRef sdkName = {}; size_t bytes = 0; Status status = Status::Malformed; }; diff --git a/lib/APIDigester/ModuleAnalyzerNodes.cpp b/lib/APIDigester/ModuleAnalyzerNodes.cpp index da9d140b1a0b5..d3b167f1cc9a4 100644 --- a/lib/APIDigester/ModuleAnalyzerNodes.cpp +++ b/lib/APIDigester/ModuleAnalyzerNodes.cpp @@ -2233,6 +2233,9 @@ swift::ide::api::getSDKNodeRoot(SDKContext &SDKCtx, auto &Ctx = CI.getASTContext(); + // Don't check if the stdlib was build with the same SDK as what is loaded + // here as some tests rely on using a different stdlib. + Ctx.SearchPathOpts.EnableSameSDKCheck = false; // Load standard library so that Clang importer can use it. auto *Stdlib = Ctx.getStdlibModule(/*loadIfAbsent=*/true); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index f20ea1969684b..40fcad55141cc 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -14,6 +14,8 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "ast-types" + #include "swift/AST/Types.h" #include "ForeignRepresentationInfo.h" #include "swift/AST/ASTContext.h" @@ -39,6 +41,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -1798,12 +1801,13 @@ class IsBindableVisitor } CanType visitDynamicSelfType(DynamicSelfType *orig, CanType subst, - ArchetypeType *, ArrayRef) { + ArchetypeType *upperBound, + ArrayRef substConformances) { // A "dynamic self" type can be bound to another dynamic self type, or the // non-dynamic base class type. if (auto dynSubst = dyn_cast(subst)) { if (auto newBase = visit(orig->getSelfType(), dynSubst.getSelfType(), - nullptr, {})) { + upperBound, substConformances)) { return CanDynamicSelfType::get(newBase, orig->getASTContext()) ->getCanonicalType(); } @@ -1811,31 +1815,274 @@ class IsBindableVisitor } if (auto newNonDynBase = visit(orig->getSelfType(), subst, - nullptr, {})) { + upperBound, substConformances)) { return newNonDynBase; } return CanType(); } + /// Handle a nominal type with generic parameters anywhere in its context. + /// \c origType and \c substType must already have been established to be + /// instantiations of the same \c NominalTypeDecl. + CanType handleGenericNominalType(NominalTypeDecl *decl, + CanType origType, + CanType substType, + ArchetypeType *upperBound, + ArrayRef substConformances) { + assert(origType->getAnyNominal() == decl + && substType->getAnyNominal() == decl); + + LLVM_DEBUG(llvm::dbgs() << "\n---\nTesting bindability of:\n"; + origType->print(llvm::dbgs()); + llvm::dbgs() << "\nto subst type:\n"; + substType->print(llvm::dbgs()); + if (upperBound) { + llvm::dbgs() << "\nwith upper bound archetype:\n"; + upperBound->print(llvm::dbgs()); + }); + + auto *moduleDecl = decl->getParentModule(); + auto origSubMap = origType->getContextSubstitutionMap( + moduleDecl, decl, decl->getGenericEnvironment()); + auto substSubMap = substType->getContextSubstitutionMap( + moduleDecl, decl, decl->getGenericEnvironment()); + + auto genericSig = decl->getGenericSignature(); + + SmallVector newParams; + llvm::DenseMap newParamsMap; + bool didChange = false; + + // The upper bounds for the nominal type's arguments may depend on the + // upper bounds imposed on the nominal type itself, if conditional + // conformances are involved. For instance, if we're looking at: + // + // protocol P {} + // struct A {} + // struct B {} + // extension B: P where U: P {} + // + // and visiting `A>`, then `B` has an upper bound of `_: P` because + // of A's generic type constraint. In order to stay within this upper bound, + // `V` must also have `_: P` as its upper bound, in order to satisfy the + // constraint on `B`. To handle this correctly, ingest requirements + // from any extension declarations providing conformances required by the + // upper bound. + auto upperBoundGenericSig = genericSig; + auto upperBoundSubstMap = substSubMap; + + LLVM_DEBUG(llvm::dbgs() << "\nNominal type generic signature:\n"; + upperBoundGenericSig.print(llvm::dbgs()); + upperBoundSubstMap.dump(llvm::dbgs())); + + if (upperBound && !upperBound->getConformsTo().empty()) { + // Start with the set of requirements from the nominal type. + SmallVector addedRequirements; + + llvm::DenseMap, ProtocolConformanceRef> addedConformances; + + for (auto proto : upperBound->getConformsTo()) { + // Find the DeclContext providing the conformance for the type. + auto nomConformance = moduleDecl->lookupConformance(substType, proto); + if (!nomConformance) + return CanType(); + if (nomConformance.isAbstract()) + continue; + auto conformanceContext = nomConformance.getConcrete()->getDeclContext(); + + LLVM_DEBUG(llvm::dbgs() << "\nFound extension conformance for " + << proto->getName() + << " in context:\n"; + conformanceContext->printContext(llvm::dbgs())); + + auto conformanceSig = conformanceContext->getGenericSignatureOfContext(); + // TODO: Conformance on generalized generic extensions could conceivably + // have totally different generic signatures. + assert(conformanceSig.getGenericParams().size() + == genericSig.getGenericParams().size() + && "generalized generic extension not handled properly"); + + // Collect requirements from the conformance not satisfied by the + // original declaration. + for (auto reqt : conformanceSig->requirementsNotSatisfiedBy(genericSig)) { + LLVM_DEBUG(llvm::dbgs() << "\n- adds requirement\n"; + reqt.dump(llvm::dbgs())); + + addedRequirements.push_back(reqt); + + // Collect the matching conformance for the substituted type. + // TODO: Look this up using the upperBoundSubstConformances + if (reqt.getKind() == RequirementKind::Conformance) { + auto proto = reqt.getSecondType()->castTo()->getDecl(); + auto substTy = reqt.getFirstType().subst(substSubMap); + ProtocolConformanceRef substConformance; + if (substTy->isTypeParameter()) { + substConformance = ProtocolConformanceRef(proto); + } else { + substConformance = moduleDecl->lookupConformance(substTy, proto); + } + + LLVM_DEBUG(llvm::dbgs() << "\n` adds conformance for subst type\n"; + substTy->print(llvm::dbgs()); + substConformance.dump(llvm::dbgs())); + + auto key = std::make_pair(reqt.getFirstType()->getCanonicalType(), + proto); + + addedConformances.insert({key, substConformance}); + } + } + } + + // Build the generic signature with the additional collected requirements. + if (!addedRequirements.empty()) { + upperBoundGenericSig = evaluateOrDefault( + decl->getASTContext().evaluator, + AbstractGenericSignatureRequest{ + upperBoundGenericSig.getPointer(), + /*genericParams=*/{ }, + std::move(addedRequirements)}, + nullptr); + upperBoundSubstMap = SubstitutionMap::get(upperBoundGenericSig, + [&](SubstitutableType *t) -> Type { + // Type substitutions remain the same as the original substitution + // map. + return Type(t).subst(substSubMap); + }, + [&](CanType dependentType, + Type conformingReplacementType, + ProtocolDecl *conformedProtocol) -> ProtocolConformanceRef { + // Check whether we added this conformance. + auto added = addedConformances.find({dependentType, + conformedProtocol}); + if (added != addedConformances.end()) { + return added->second; + } + // Otherwise, use the conformance from the original map. + + return substSubMap.lookupConformance(dependentType, conformedProtocol); + }); + + LLVM_DEBUG(llvm::dbgs() << "\nGeneric signature with conditional reqts:\n"; + upperBoundGenericSig.print(llvm::dbgs()); + upperBoundSubstMap.dump(llvm::dbgs())); + } + } + + auto upperBoundGenericEnv = upperBoundGenericSig.getGenericEnvironment(); + + for (auto gpTy : upperBoundGenericSig.getGenericParams()) { + auto gp = gpTy->getCanonicalType(); + + auto orig = gp.subst(origSubMap)->getCanonicalType(); + auto subst = gp.subst(substSubMap)->getCanonicalType(); + + // The new type is upper-bounded by the constraints the nominal type + // requires. The substitution operation may be interested in transforming + // the substituted type's conformances to these protocols. + // + // FIXME: The upperBound on the nominal type itself may impose additional + // requirements on the type parameters due to conditional conformances. + // These are currently not considered, leading to invalid generic signatures + // built during SILGen. + auto paramUpperBound = + GenericEnvironment::mapTypeIntoContext(upperBoundGenericEnv, gp) + ->getAs(); + SmallVector paramSubstConformances; + if (paramUpperBound) { + for (auto proto : paramUpperBound->getConformsTo()) { + auto conformance = upperBoundSubstMap.lookupConformance(gp, proto); + if (!conformance) + return CanType(); + paramSubstConformances.push_back(conformance); + } + } + + auto newParam = visit(orig, subst, paramUpperBound, + paramSubstConformances); + if (!newParam) + return CanType(); + + newParams.push_back(newParam); + newParamsMap.insert({gp->castTo(), newParam}); + didChange |= (newParam != subst); + } + + SmallVector newConformances; + + // Collect conformances for the new substitutions, and verify that they don't + // invalidate the binding to the original type. + for (const auto &req : genericSig.getRequirements()) { + if (req.getKind() != RequirementKind::Conformance) continue; + + auto canTy = req.getFirstType()->getCanonicalType(); + + // Verify the generic requirements, if the subst type is bound to + // concrete type. + auto *proto = req.getProtocolDecl(); + if (!canTy.subst(substSubMap)->isTypeParameter()) { + auto origConf = origSubMap.lookupConformance(canTy, proto); + auto substConf = substSubMap.lookupConformance(canTy, proto); + + if (origConf.isConcrete()) { + // A generic argument may inherit a concrete conformance from a class + // constraint, which could still be bound to a type parameter we don't + // know more about. + if (origConf.getConcrete()->getType()->is()) + continue; + + if (!substConf.isConcrete()) + return CanType(); + if (origConf.getConcrete()->getRootConformance() + != substConf.getConcrete()->getRootConformance()) + return CanType(); + } + } + + // Gather the conformances for the new binding type, if the type changed. + if (didChange) { + auto newSubstTy = req.getFirstType().subst( + QueryTypeSubstitutionMap{newParamsMap}, + LookUpConformanceInModule(moduleDecl)); + + if (newSubstTy->isTypeParameter()) { + newConformances.push_back(ProtocolConformanceRef(proto)); + } else { + auto newConformance + = moduleDecl->lookupConformance(newSubstTy, proto); + if (!newConformance) + return CanType(); + newConformances.push_back(newConformance); + } + } + } + + if (!didChange) + return substType; + + // Build the new substituted generic type. + auto newSubMap = SubstitutionMap::get(genericSig, + newParams, + newConformances); + return decl->getDeclaredInterfaceType().subst(newSubMap) + ->getCanonicalType(); + } + CanType visitNominalType(NominalType *nom, CanType subst, - ArchetypeType*, ArrayRef) { + ArchetypeType* upperBound, + ArrayRef substConformances) { if (auto substNom = dyn_cast(subst)) { + auto nomDecl = nom->getDecl(); if (nom->getDecl() != substNom->getDecl()) return CanType(); - // Same decl should always either have or not have a parent. - assert((bool)nom->getParent() == (bool)substNom->getParent()); - - if (nom->getParent()) { - auto substParent = visit(nom->getParent()->getCanonicalType(), - substNom->getParent()->getCanonicalType(), - nullptr, {}); - if (substParent == substNom.getParent()) - return subst; - return NominalType::get(nom->getDecl(), substParent, - nom->getASTContext()) - ->getCanonicalType(); + // If the type is generic (because it's a nested type in a generic context), + // process the generic type bindings. + if (!isa(nomDecl) && nomDecl->isGenericContext()) { + return handleGenericNominalType(nomDecl, CanType(nom), subst, + upperBound, substConformances); } + // Otherwise, the nongeneric nominal types trivially match. return subst; } return CanType(); @@ -2055,7 +2302,8 @@ class IsBindableVisitor } CanType visitBoundGenericType(BoundGenericType *bgt, CanType subst, - ArchetypeType *, ArrayRef) { + ArchetypeType *upperBound, + ArrayRef substConformances) { auto substBGT = dyn_cast(subst); if (!substBGT) return CanType(); @@ -2065,95 +2313,8 @@ class IsBindableVisitor auto *decl = bgt->getDecl(); - auto *moduleDecl = decl->getParentModule(); - auto origSubMap = bgt->getContextSubstitutionMap( - moduleDecl, decl, decl->getGenericEnvironment()); - auto substSubMap = substBGT->getContextSubstitutionMap( - moduleDecl, decl, decl->getGenericEnvironment()); - - auto genericSig = decl->getGenericSignature(); - - // Same decl should always either have or not have a parent. - assert((bool)bgt->getParent() == (bool)substBGT->getParent()); - CanType newParent; - if (bgt->getParent()) { - newParent = visit(bgt->getParent()->getCanonicalType(), - substBGT.getParent(), - nullptr, {}); - if (!newParent) - return CanType(); - } - - SmallVector newParams; - bool didChange = newParent != substBGT.getParent(); - - auto depthStart = - genericSig.getGenericParams().size() - bgt->getGenericArgs().size(); - for (auto i : indices(bgt->getGenericArgs())) { - auto orig = bgt->getGenericArgs()[i]->getCanonicalType(); - auto subst = substBGT.getGenericArgs()[i]; - auto gp = genericSig.getGenericParams()[depthStart + i]; - - // The new type is upper-bounded by the constraints the nominal type - // requires. The substitution operation may be interested in transforming - // the substituted type's conformances to these protocols. - auto upperBoundArchetype = decl->mapTypeIntoContext(gp) - ->getAs(); - SmallVector substConformances; - if (upperBoundArchetype) { - for (auto proto : upperBoundArchetype->getConformsTo()) { - auto conformance = substSubMap.lookupConformance(gp->getCanonicalType(), - proto); - if (!conformance) - return CanType(); - substConformances.push_back(conformance); - } - } - - auto newParam = visit(orig, subst, upperBoundArchetype, - substConformances); - if (!newParam) - return CanType(); - - newParams.push_back(newParam); - didChange |= (newParam != subst); - } - - for (const auto &req : genericSig.getRequirements()) { - if (req.getKind() != RequirementKind::Conformance) continue; - - auto canTy = req.getFirstType()->getCanonicalType(); - - // If the substituted type is an interface type, we can't verify the - // generic requirements. - if (canTy.subst(substSubMap)->isTypeParameter()) - continue; - - auto *proto = req.getProtocolDecl(); - auto origConf = origSubMap.lookupConformance(canTy, proto); - auto substConf = substSubMap.lookupConformance(canTy, proto); - - if (origConf.isConcrete()) { - // A generic argument may inherit a concrete conformance from a class - // constraint, which could still be bound to a type parameter we don't - // know more about. - if (origConf.getConcrete()->getType()->is()) - continue; - - if (!substConf.isConcrete()) - return CanType(); - if (origConf.getConcrete()->getRootConformance() - != substConf.getConcrete()->getRootConformance()) - return CanType(); - } - } - - if (!didChange) - return subst; - - return BoundGenericType::get(substBGT->getDecl(), - newParent, newParams) - ->getCanonicalType(); + return handleGenericNominalType(decl, CanType(bgt), subst, + upperBound, substConformances); } }; } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 57ef9958233b8..40f3a44a0af90 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -429,6 +429,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.EnableExperimentalConcurrency |= Args.hasArg(OPT_enable_experimental_concurrency); + Opts.EnableExperimentalDefinedLifetimes |= + Args.hasArg(OPT_enable_experimental_defined_lifetimes); + Opts.EnableExperimentalNamedOpaqueTypes |= Args.hasArg(OPT_enable_experimental_named_opaque_types); @@ -774,6 +777,11 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, } } + // Get the SDK name. + if (Arg *A = Args.getLastArg(options::OPT_target_sdk_name)) { + Opts.SDKName = A->getValue(); + } + if (const Arg *A = Args.getLastArg(OPT_entry_point_function_name)) { Opts.entryPointFunctionName = A->getValue(); } @@ -1900,6 +1908,26 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args, Opts.VirtualFunctionElimination = true; } + // Default to disabling swift async extended frame info on anything but + // darwin. Other platforms are unlikely to have support for extended frame + // pointer information. + if (!Triple.isOSDarwin()) { + Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Never; + } + if (const Arg *A = Args.getLastArg(OPT_swift_async_frame_pointer_EQ)) { + StringRef mode(A->getValue()); + if (mode == "auto") + Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Auto; + else if (mode == "always") + Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Always; + else if (mode == "never") + Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Never; + else { + Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, + A->getAsString(Args), A->getValue()); + } + } + return false; } diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 28865e0bad368..6c30b4b4d7eaf 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -151,6 +151,7 @@ SerializationOptions CompilerInvocation::computeSerializationOptions( serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs; serializationOpts.PublicDependentLibraries = getIRGenOptions().PublicLinkLibraries; + serializationOpts.SDKName = getLangOptions().SDKName; if (opts.EmitSymbolGraph) { if (!opts.SymbolGraphOutputDir.empty()) { diff --git a/lib/Frontend/ModuleInterfaceBuilder.cpp b/lib/Frontend/ModuleInterfaceBuilder.cpp index 4c8a3e18579da..19a3240826c5b 100644 --- a/lib/Frontend/ModuleInterfaceBuilder.cpp +++ b/lib/Frontend/ModuleInterfaceBuilder.cpp @@ -257,6 +257,8 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal( if (!getRelativeDepPath(InPath, SDKPath)) SerializationOpts.ModuleInterface = InPath; + SerializationOpts.SDKName = SubInstance.getASTContext().LangOpts.SDKName; + SmallVector Deps; bool serializeHashes = FEOpts.SerializeModuleInterfaceDependencyHashes; if (collectDepsForSerialization(SubInstance, Deps, serializeHashes)) { diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp index 576d491e13128..25cda2f5d2232 100644 --- a/lib/IRGen/IRGen.cpp +++ b/lib/IRGen/IRGen.cpp @@ -180,6 +180,18 @@ swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx) { TargetOpts.GlobalISelAbort = GlobalISelAbortMode::DisableWithDiag; } + switch (Opts.SwiftAsyncFramePointer) { + case SwiftAsyncFramePointerKind::Never: + TargetOpts.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never; + break; + case SwiftAsyncFramePointerKind::Auto: + TargetOpts.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::DeploymentBased; + break; + case SwiftAsyncFramePointerKind::Always: + TargetOpts.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always; + break; + } + clang::TargetOptions &ClangOpts = Clang->getTargetInfo().getTargetOpts(); return std::make_tuple(TargetOpts, ClangOpts.CPU, ClangOpts.Features, ClangOpts.Triple); } diff --git a/lib/SIL/IR/SILInstructions.cpp b/lib/SIL/IR/SILInstructions.cpp index af7136eb5f2a7..c4287dcf68dc7 100644 --- a/lib/SIL/IR/SILInstructions.cpp +++ b/lib/SIL/IR/SILInstructions.cpp @@ -191,13 +191,13 @@ SILDebugVariable::createFromAllocation(const AllocationInst *AI) { AllocStackInst::AllocStackInst(SILDebugLocation Loc, SILType elementType, ArrayRef TypeDependentOperands, SILFunction &F, Optional Var, - bool hasDynamicLifetime) + bool hasDynamicLifetime, bool isLexical) : InstructionBase(Loc, elementType.getAddressType()), SILDebugVariableSupplement(Var ? Var->DIExpr.getNumElements() : 0, Var ? Var->Type.hasValue() : false, Var ? Var->Loc.hasValue() : false, Var ? Var->Scope != nullptr : false), - dynamicLifetime(hasDynamicLifetime) { + dynamicLifetime(hasDynamicLifetime), lexical(isLexical) { SILNode::Bits.AllocStackInst.NumOperands = TypeDependentOperands.size(); assert(SILNode::Bits.AllocStackInst.NumOperands == @@ -219,19 +219,18 @@ AllocStackInst::AllocStackInst(SILDebugLocation Loc, SILType elementType, TypeDependentOperands); } -AllocStackInst * -AllocStackInst::create(SILDebugLocation Loc, - SILType elementType, SILFunction &F, - Optional Var, - bool hasDynamicLifetime) { +AllocStackInst *AllocStackInst::create(SILDebugLocation Loc, + SILType elementType, SILFunction &F, + Optional Var, + bool hasDynamicLifetime, + bool isLexical) { SmallVector TypeDependentOperands; collectTypeDependentOperands(TypeDependentOperands, F, elementType.getASTType()); void *Buffer = allocateDebugVarCarryingInst( F.getModule(), Var, TypeDependentOperands); - return ::new (Buffer) - AllocStackInst(Loc, elementType, TypeDependentOperands, F, Var, - hasDynamicLifetime); + return ::new (Buffer) AllocStackInst(Loc, elementType, TypeDependentOperands, + F, Var, hasDynamicLifetime, isLexical); } VarDecl *AllocationInst::getDecl() const { diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index c6d01608f221f..27154679f0c5f 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -1260,6 +1260,8 @@ class SILPrinter : public SILInstructionVisitor { void visitAllocStackInst(AllocStackInst *AVI) { if (AVI->hasDynamicLifetime()) *this << "[dynamic_lifetime] "; + if (AVI->isLexical()) + *this << "[lexical] "; *this << AVI->getElementType(); printDebugVar(AVI->getVarInfo(), &AVI->getModule().getASTContext().SourceMgr); diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index de0f724a27b71..fe515018de8b3 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -4142,34 +4142,60 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B, break; } - case SILInstructionKind::AllocStackInst: - case SILInstructionKind::MetatypeInst: { - + case SILInstructionKind::AllocStackInst: { bool hasDynamicLifetime = false; - if (Opcode == SILInstructionKind::AllocStackInst && - parseSILOptional(hasDynamicLifetime, *this, "dynamic_lifetime")) + bool isLexical = false; + + while (P.consumeIf(tok::l_square)) { + Identifier ident; + SourceLoc identLoc; + if (parseSILIdentifier(ident, identLoc, + diag::expected_in_attribute_list)) { + if (P.consumeIf(tok::r_square)) { + continue; + } else { + return true; + } + } + StringRef attr = ident.str(); + + if (attr == "dynamic_lifetime") { + hasDynamicLifetime = true; + } else if (attr == "lexical") { + isLexical = true; + } else { + return true; + } + + if (!P.consumeIf(tok::r_square)) + return true; + } + + SILType Ty; + if (parseSILType(Ty)) return true; + SILDebugVariable VarInfo; + if (parseSILDebugVar(VarInfo) || parseSILDebugLocation(InstLoc, B)) + return true; + // It doesn't make sense to attach a debug var info if the name is empty + if (VarInfo.Name.size()) + ResultVal = B.createAllocStack(InstLoc, Ty, VarInfo, hasDynamicLifetime, + isLexical); + else + ResultVal = + B.createAllocStack(InstLoc, Ty, {}, hasDynamicLifetime, isLexical); + break; + } + case SILInstructionKind::MetatypeInst: { SILType Ty; if (parseSILType(Ty)) return true; - if (Opcode == SILInstructionKind::AllocStackInst) { - SILDebugVariable VarInfo; - if (parseSILDebugVar(VarInfo) || parseSILDebugLocation(InstLoc, B)) - return true; - // It doesn't make sense to attach a debug var info if the name is empty - if (VarInfo.Name.size()) - ResultVal = - B.createAllocStack(InstLoc, Ty, VarInfo, hasDynamicLifetime); - else - ResultVal = B.createAllocStack(InstLoc, Ty, {}, hasDynamicLifetime); - } else { - assert(Opcode == SILInstructionKind::MetatypeInst); - if (parseSILDebugLocation(InstLoc, B)) - return true; - ResultVal = B.createMetatype(InstLoc, Ty); - } + assert(Opcode == SILInstructionKind::MetatypeInst); + if (parseSILDebugLocation(InstLoc, B)) + return true; + ResultVal = B.createMetatype(InstLoc, Ty); break; } case SILInstructionKind::AllocRefInst: diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index ef006a5afb283..e186988fc9de6 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -3200,6 +3200,7 @@ class SILVerifier : public SILVerifierBase { } SILType getMethodSelfType(CanSILFunctionType ft) { + SILFunctionConventions fnConv(ft, F.getModule()); return fnConv.getSILType(ft->getParameters().back(), F.getTypeExpansionContext()); } diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp index c0be640f610e8..6b845416583d4 100644 --- a/lib/SILGen/SILGenDecl.cpp +++ b/lib/SILGen/SILGenDecl.cpp @@ -271,6 +271,10 @@ class DestroyLocalVariable : public Cleanup { void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override { + SILValue val = SGF.VarLocs[Var].value; + if (SGF.getASTContext().LangOpts.EnableExperimentalDefinedLifetimes && + val->getOwnershipKind() != OwnershipKind::None) + SGF.B.createEndBorrow(l, val); SGF.destroyLocalVariable(l, Var); } @@ -537,13 +541,18 @@ class LetValueInitialization : public Initialization { // an argument, for example. if (value->getType().isAddress()) address = value; + SILLocation PrologueLoc(vd); + + if (SGF.getASTContext().LangOpts.EnableExperimentalDefinedLifetimes && + value->getOwnershipKind() != OwnershipKind::None) + value = SILValue( + SGF.B.createBeginBorrow(PrologueLoc, value, /*defined*/ true)); SGF.VarLocs[vd] = SILGenFunction::VarLoc::get(value); // Emit a debug_value[_addr] instruction to record the start of this value's // lifetime, if permitted to do so. if (!EmitDebugValueOnInit) return; - SILLocation PrologueLoc(vd); PrologueLoc.markAsPrologue(); SILDebugVariable DbgVar(vd->isLet(), /*ArgNo=*/0); SGF.B.emitDebugDescription(PrologueLoc, value, DbgVar); @@ -1723,8 +1732,16 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) { // For 'let' bindings, we emit a release_value or destroy_addr, depending on // whether we have an address or not. SILValue Val = loc.value; - if (!Val->getType().isAddress()) - B.emitDestroyValueOperation(silLoc, Val); - else + if (!Val->getType().isAddress()) { + SILValue valueToBeDestroyed; + if (getASTContext().LangOpts.EnableExperimentalDefinedLifetimes && + Val->getOwnershipKind() != OwnershipKind::None) { + auto *inst = cast(Val.getDefiningInstruction()); + valueToBeDestroyed = inst->getOperand(); + } else { + valueToBeDestroyed = Val; + } + B.emitDestroyValueOperation(silLoc, valueToBeDestroyed); + } else B.createDestroyAddr(silLoc, Val); } diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index 0133920666982..2e9946839dcf0 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -1223,12 +1223,15 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, Loc, cast(MF->getType(TyID)->getCanonicalType()), None, /*bool hasDynamicLifetime*/ Attr != 0); break; - case SILInstructionKind::AllocStackInst: + case SILInstructionKind::AllocStackInst: { assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType."); + bool hasDynamicLifetime = Attr & 0x1; + bool isLexical = (Attr >> 1) & 0x1; ResultInst = Builder.createAllocStack( Loc, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn), - None, /*bool hasDynamicLifetime*/ Attr != 0); + None, hasDynamicLifetime, isLexical); break; + } case SILInstructionKind::MetatypeInst: assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType."); ResultInst = Builder.createMetatype( diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp index 1d2aeeb027679..38990f4b4e4c5 100644 --- a/lib/Serialization/ModuleFile.cpp +++ b/lib/Serialization/ModuleFile.cpp @@ -149,6 +149,15 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc, return error(status); } + auto clientSDK = ctx.LangOpts.SDKName; + StringRef moduleSDK = Core->SDKName; + if (ctx.SearchPathOpts.EnableSameSDKCheck && + !moduleSDK.empty() && !clientSDK.empty() && + moduleSDK != clientSDK) { + status = Status::SDKMismatch; + return error(status); + } + for (const auto &searchPath : Core->SearchPaths) ctx.addSearchPath(searchPath.Path, searchPath.IsFramework, searchPath.IsSystem); diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp index 8fba7e2ed85b1..eeec9a2fef78b 100644 --- a/lib/Serialization/ModuleFileSharedCore.cpp +++ b/lib/Serialization/ModuleFileSharedCore.cpp @@ -299,6 +299,10 @@ validateControlBlock(llvm::BitstreamCursor &cursor, case control_block::TARGET: result.targetTriple = blobData; break; + case control_block::SDK_NAME: { + result.sdkName = blobData; + break; + } default: // Unknown metadata record, possibly for use by a future version of the // module format. @@ -1210,6 +1214,7 @@ ModuleFileSharedCore::ModuleFileSharedCore( } Name = info.name; TargetTriple = info.targetTriple; + SDKName = info.sdkName; CompatibilityVersion = info.compatibilityVersion; UserModuleVersion = info.userModuleVersion; Bits.ArePrivateImportsEnabled = extInfo.arePrivateImportsEnabled(); diff --git a/lib/Serialization/ModuleFileSharedCore.h b/lib/Serialization/ModuleFileSharedCore.h index e192013c596fc..7f8fde8b28461 100644 --- a/lib/Serialization/ModuleFileSharedCore.h +++ b/lib/Serialization/ModuleFileSharedCore.h @@ -58,6 +58,9 @@ class ModuleFileSharedCore { /// The target the module was built for. StringRef TargetTriple; + /// The canonical name of the SDK the module was built with. + StringRef SDKName; + /// The name of the module interface this module was compiled from. /// /// Empty if this module didn't come from an interface file. diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 599ef3e5c0570..18e9530e8612e 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 628; // unaligned pointer +const uint16_t SWIFTMODULE_VERSION_MINOR = 629; // BuilderSDK /// A standard hash seed used for all string hashes in a serialized module. /// @@ -754,7 +754,8 @@ namespace control_block { enum { METADATA = 1, MODULE_NAME, - TARGET + TARGET, + SDK_NAME }; using MetadataLayout = BCRecordLayout< @@ -779,6 +780,11 @@ namespace control_block { TARGET, BCBlob // LLVM triple >; + + using SDKNameLayout = BCRecordLayout< + SDK_NAME, + BCBlob + >; } /// The record types within the options block (a sub-block of the control diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 21d1210e9772e..a1f10d7719045 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -806,6 +806,7 @@ void Serializer::writeBlockInfoBlock() { BLOCK_RECORD(control_block, METADATA); BLOCK_RECORD(control_block, MODULE_NAME); BLOCK_RECORD(control_block, TARGET); + BLOCK_RECORD(control_block, SDK_NAME); BLOCK(OPTIONS_BLOCK); BLOCK_RECORD(options_block, SDK_PATH); @@ -956,6 +957,7 @@ void Serializer::writeHeader(const SerializationOptions &options) { control_block::ModuleNameLayout ModuleName(Out); control_block::MetadataLayout Metadata(Out); control_block::TargetLayout Target(Out); + control_block::SDKNameLayout SDKName(Out); ModuleName.emit(ScratchRecord, M->getName().str()); @@ -989,6 +991,9 @@ void Serializer::writeHeader(const SerializationOptions &options) { userModuleSubminor, userModuleBuild, versionString.str()); + if (!options.SDKName.empty()) + SDKName.emit(ScratchRecord, options.SDKName); + Target.emit(ScratchRecord, M->getASTContext().LangOpts.Target.str()); { diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 66bb631a40461..56d37af5879ae 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -1014,8 +1014,9 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) { } case SILInstructionKind::AllocStackInst: { const AllocStackInst *ASI = cast(&SI); - writeOneTypeLayout(ASI->getKind(), ASI->hasDynamicLifetime() ? 1 : 0, - ASI->getElementType()); + unsigned attr = + unsigned(ASI->hasDynamicLifetime()) + unsigned(ASI->isLexical() << 1); + writeOneTypeLayout(ASI->getKind(), attr, ASI->getElementType()); break; } case SILInstructionKind::ProjectValueBufferInst: { diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 57c3443143717..5d5dac786cd21 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -976,6 +976,13 @@ void swift::serialization::diagnoseSerializedASTLoadFailure( moduleOSInfo.second, moduleBufferID); break; } + + case serialization::Status::SDKMismatch: + auto currentSDK = Ctx.LangOpts.SDKName; + auto moduleSDK = loadInfo.sdkName; + Ctx.Diags.diagnose(diagLoc, diag::serialization_sdk_mismatch, + ModuleName, moduleSDK, currentSDK, moduleBufferID); + break; } } diff --git a/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift b/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift index 7904d43015b19..db1919bb81be5 100644 --- a/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift +++ b/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift @@ -131,6 +131,19 @@ import Glibc let rtldDefault: UnsafeMutableRawPointer? = nil +#if INTERNAL_CHECKS_ENABLED +@_silgen_name("swift_getMetadataSection") +internal func _getMetadataSection(_ index: UInt) -> UnsafeRawPointer? + +@_silgen_name("swift_getMetadataSectionCount") +internal func _getMetadataSectionCount() -> UInt + +@_silgen_name("swift_getMetadataSectionName") +internal func _getMetadataSectionName( + _ metadata_section: UnsafeRawPointer +) -> UnsafePointer +#endif + extension Section { init(range: MetadataSectionRange) { self.startAddress = UnsafeRawPointer(bitPattern: range.start)! @@ -139,6 +152,7 @@ extension Section { } internal func getReflectionInfoForImage(atIndex i: UInt32) -> ReflectionInfo? { +#if INTERNAL_CHECKS_ENABLED return _getMetadataSection(UInt(i)).map { rawPointer in let name = _getMetadataSectionName(rawPointer) let metadataSection = rawPointer.bindMemory(to: MetadataSections.self, capacity: 1).pointee @@ -150,10 +164,17 @@ internal func getReflectionInfoForImage(atIndex i: UInt32) -> ReflectionInfo? { typeref: Section(range: metadataSection.swift5_typeref), reflstr: Section(range: metadataSection.swift5_reflstr)) } +#else + return nil +#endif } internal func getImageCount() -> UInt32 { +#if INTERNAL_CHECKS_ENABLED return UInt32(_getMetadataSectionCount()) +#else + return 0 +#endif } internal func sendImages() { diff --git a/stdlib/public/BackDeployConcurrency/CMakeLists.txt b/stdlib/public/BackDeployConcurrency/CMakeLists.txt index beabf8a25bd42..514120348a080 100644 --- a/stdlib/public/BackDeployConcurrency/CMakeLists.txt +++ b/stdlib/public/BackDeployConcurrency/CMakeLists.txt @@ -46,5 +46,6 @@ set(swift_concurrency_options set(swift_concurrency_extra_sources "../BackDeployConcurrency/Exclusivity.cpp" "../BackDeployConcurrency/Metadata.cpp") +set(swift_concurrency_async_fp_mode "never") add_subdirectory(../Concurrency stdlib/public/BackDeployConcurrency) diff --git a/stdlib/public/Concurrency/CMakeLists.txt b/stdlib/public/Concurrency/CMakeLists.txt index 7376eac880275..c35cac8d85936 100644 --- a/stdlib/public/Concurrency/CMakeLists.txt +++ b/stdlib/public/Concurrency/CMakeLists.txt @@ -31,6 +31,26 @@ if(SWIFT_CONCURRENCY_USES_DISPATCH) endif() endif() + +set(SWIFT_RUNTIME_CONCURRENCY_C_FLAGS) +set(SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS) + +if(NOT swift_concurrency_async_fp_mode) + set(swift_concurrency_async_fp_mode "always") +endif() + +# Don't emit extended frame info on platforms other than darwin, system +# backtracer and system debugger are unlikely to support it. +if(CMAKE_SYSTEM_NAME STREQUAL Darwin) + list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS + "-fswift-async-fp=${swift_concurrency_async_fp_mode}") + list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS + "-Xfrontend" + "-swift-async-frame-pointer=${swift_concurrency_async_fp_mode}") +else() + list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS "-fswift-async-fp=never") +endif() + add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB ../CompatibilityOverride/CompatibilityOverride.cpp Actor.cpp @@ -91,13 +111,14 @@ add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I LINK_LIBRARIES ${swift_concurrency_link_libraries} C_COMPILE_FLAGS - -Dswift_Concurrency_EXPORTS + -Dswift_Concurrency_EXPORTS ${SWIFT_RUNTIME_CONCURRENCY_C_FLAGS} SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS} -parse-stdlib -Xfrontend -enable-experimental-concurrency -Xfrontend -define-availability -Xfrontend "SwiftStdlib 5.5:macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0" + ${SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS} LINK_FLAGS "${SWIFT_RUNTIME_CONCURRENCY_SWIFT_LINK_FLAGS}" ${swift_concurrency_options} INSTALL_IN_COMPONENT ${swift_concurrency_install_component} diff --git a/stdlib/public/core/Misc.swift b/stdlib/public/core/Misc.swift index 2b63a7f69c93c..469ac429b8ee8 100644 --- a/stdlib/public/core/Misc.swift +++ b/stdlib/public/core/Misc.swift @@ -118,17 +118,3 @@ public func _getTypeByMangledNameInContext( genericContext: UnsafeRawPointer?, genericArguments: UnsafeRawPointer?) -> Any.Type? - -@_silgen_name("swift_getMetadataSection") -public func _getMetadataSection( - _ index: UInt) - -> UnsafeRawPointer? - -@_silgen_name("swift_getMetadataSectionCount") -public func _getMetadataSectionCount() - -> UInt - -@_silgen_name("swift_getMetadataSectionName") -public func _getMetadataSectionName( - _ metadata_section: UnsafeRawPointer) - -> UnsafePointer diff --git a/stdlib/public/core/Set.swift b/stdlib/public/core/Set.swift index f4fb463fe24db..2567b656e0f74 100644 --- a/stdlib/public/core/Set.swift +++ b/stdlib/public/core/Set.swift @@ -1123,7 +1123,15 @@ extension Set { /// otherwise, `false`. @inlinable public func isDisjoint(with other: Set) -> Bool { - return _isDisjoint(with: other) + guard !isEmpty && !other.isEmpty else { return true } + let (smaller, larger) = + count < other.count ? (self, other) : (other, self) + for member in smaller { + if larger.contains(member) { + return false + } + } + return true } @inlinable diff --git a/stdlib/public/runtime/ImageInspectionCommon.cpp b/stdlib/public/runtime/ImageInspectionCommon.cpp index fa2d58a311fe5..c70e886c06806 100644 --- a/stdlib/public/runtime/ImageInspectionCommon.cpp +++ b/stdlib/public/runtime/ImageInspectionCommon.cpp @@ -131,9 +131,10 @@ void swift::initializeTypeMetadataRecordLookup() { void swift::initializeDynamicReplacementLookup() { } +#ifndef NDEBUG + SWIFT_RUNTIME_EXPORT const swift::MetadataSections *swift_getMetadataSection(size_t index) { - #ifndef NDEBUG if (swift::registered == nullptr) { return nullptr; } @@ -147,27 +148,21 @@ const swift::MetadataSections *swift_getMetadataSection(size_t index) { --index; } return selected; - #else // NDEBUG - return nullptr; - #endif // else NDEBUG } SWIFT_RUNTIME_EXPORT const char *swift_getMetadataSectionName(void *metadata_section) { - #ifndef NDEBUG swift::SymbolInfo info; if (lookupSymbol(metadata_section, &info)) { if (info.fileName) { return info.fileName; } } - #endif // NDEBUG return ""; } SWIFT_RUNTIME_EXPORT size_t swift_getMetadataSectionCount() { - #ifndef NDEBUG if (swift::registered == nullptr) return 0; @@ -176,10 +171,10 @@ size_t swift_getMetadataSectionCount() { current != swift::registered; current = current->next, ++count); return count; - #else // NDEBUG - return 0; - #endif // else NDEBUG } + +#endif // NDEBUG + #endif // !defined(__MACH__) #endif // SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H \ No newline at end of file diff --git a/stdlib/public/runtime/SwiftDtoa.cpp b/stdlib/public/runtime/SwiftDtoa.cpp index a1720157ee404..d1f3c1cb090e3 100644 --- a/stdlib/public/runtime/SwiftDtoa.cpp +++ b/stdlib/public/runtime/SwiftDtoa.cpp @@ -1,4 +1,4 @@ -//===--- SwiftDtoa.c ---------------------------------------------*- c -*-===// +//===--- SwiftDtoa.cpp ---------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // diff --git a/stdlib/public/stubs/Stubs.cpp b/stdlib/public/stubs/Stubs.cpp index cd53f51c6c2d0..9e80c0af25663 100644 --- a/stdlib/public/stubs/Stubs.cpp +++ b/stdlib/public/stubs/Stubs.cpp @@ -265,16 +265,19 @@ swift_stdlib_readLine_stdin(unsigned char **LinePtr) { #endif } -#if defined(__CYGWIN__) || defined(_WIN32) - #define strcasecmp _stricmp -#endif - static bool swift_stringIsSignalingNaN(const char *nptr) { if (nptr[0] == '+' || nptr[0] == '-') { ++nptr; } - return strcasecmp(nptr, "snan") == 0; + if ((nptr[0] == 's' || nptr[0] == 'S') && + (nptr[1] == 'n' || nptr[1] == 'N') && + (nptr[2] == 'a' || nptr[2] == 'A') && + (nptr[3] == 'n' || nptr[3] == 'N') && (nptr[4] == '\0')) { + return true; + } + + return false; } // This implementation should only be used on platforms without the diff --git a/test/DebugInfo/compileunit-sysroot-sdk.swift b/test/DebugInfo/compileunit-sysroot-sdk.swift index 0000a5f50e58d..283616f480b5b 100644 --- a/test/DebugInfo/compileunit-sysroot-sdk.swift +++ b/test/DebugInfo/compileunit-sysroot-sdk.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend %s -emit-ir -g -o - \ +// RUN: %target-swift-frontend %s -emit-ir -g -o - -parse-stdlib \ // RUN: -sdk /SWIFT_SYSROOT/MacOSX.sdk | %FileCheck %s // Test that sysroot and SDK are stored in the debug info. // CHECK: distinct !DICompileUnit({{.*}}sysroot: "/SWIFT_SYSROOT/MacOSX.sdk", diff --git a/test/IRGen/swift_async_extended_frame_info.swift b/test/IRGen/swift_async_extended_frame_info.swift new file mode 100644 index 0000000000000..70349cddd2c03 --- /dev/null +++ b/test/IRGen/swift_async_extended_frame_info.swift @@ -0,0 +1,23 @@ +// RUN: %target-swift-frontend -disable-availability-checking -target x86_64-apple-macosx11 %s -S | %FileCheck -check-prefix=ALWAYS %s +// RUN: %target-swift-frontend -disable-availability-checking -target x86_64-apple-macosx12 %s -S | %FileCheck -check-prefix=ALWAYS %s +// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=auto -target x86_64-apple-macosx11 %s -S | %FileCheck -check-prefix=AUTO %s +// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=auto -target x86_64-apple-macosx12 %s -S | %FileCheck -check-prefix=ALWAYS %s +// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=never -target x86_64-apple-macosx11 %s -S | %FileCheck -check-prefix=NEVER %s +// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=never -target x86_64-apple-macosx12 %s -S | %FileCheck -check-prefix=NEVER %s +// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=always -target x86_64-apple-macosx11 %s -S | %FileCheck -check-prefix=ALWAYS %s +// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=always -target x86_64-apple-macosx12 %s -S | %FileCheck -check-prefix=ALWAYS %s + +// REQUIRES: OS=macosx + +public func someAsyncFunction() async { +} + +// AUTO: s31swift_async_extended_frame_info17someAsyncFunctionyyYaF: +// AUTO: _swift_async_extendedFramePointerFlags + +// ALWAYS: s31swift_async_extended_frame_info17someAsyncFunctionyyYaF: +// ALWAYS: btsq $60 + +// NEVER: s31swift_async_extended_frame_info17someAsyncFunctionyyYaF: +// NEVER-NOT: _swift_async_extendedFramePointerFlags +// NEVER-NOT: btsq $60 diff --git a/test/ModuleInterface/arm64e-fallback.swift b/test/ModuleInterface/arm64e-fallback.swift index b7e448e2128c4..04bd82ef43175 100644 --- a/test/ModuleInterface/arm64e-fallback.swift +++ b/test/ModuleInterface/arm64e-fallback.swift @@ -11,7 +11,9 @@ // When run on arm64e, this tests that we build the same interface with // `#if _ptrauth(_arm64e)` on. // -// REQUIRES: CPU=arm64 || CPU=arm64e +// REQUIRES: CPU=arm64 +// Disabled arm64e for now since it isn't passing tests on apple silicon. +// XFAIL: CPU=arm64e import PtrAuthFramework // expected-remark{{rebuilding module 'PtrAuthFramework' from interface}} diff --git a/test/SIL/Parser/basic.sil b/test/SIL/Parser/basic.sil index 809e0596dace6..748f3358821a5 100644 --- a/test/SIL/Parser/basic.sil +++ b/test/SIL/Parser/basic.sil @@ -1230,6 +1230,27 @@ bb0: return %2 : $() } +// CHECK-LABEL: sil @test_alloc_stack_flags +sil @test_alloc_stack_flags : $() -> () { + // CHECK: alloc_stack $Builtin.NativeObjec + %instance = alloc_stack $Builtin.NativeObject + dealloc_stack %instance : $*Builtin.NativeObject + // CHECK: alloc_stack [dynamic_lifetime] + %instance2 = alloc_stack [dynamic_lifetime] $Builtin.NativeObject + dealloc_stack %instance2 : $*Builtin.NativeObject + // CHECK: alloc_stack [lexical] + %instance3 = alloc_stack [lexical] $Builtin.NativeObject + dealloc_stack %instance3 : $*Builtin.NativeObject + // CHECK: alloc_stack [dynamic_lifetime] [lexical] + %instance4 = alloc_stack [dynamic_lifetime] [lexical] $Builtin.NativeObject + dealloc_stack %instance4 : $*Builtin.NativeObject + // CHECK: alloc_stack [dynamic_lifetime] [lexical] + %instance5 = alloc_stack [lexical] [dynamic_lifetime] $Builtin.NativeObject + dealloc_stack %instance5 : $*Builtin.NativeObject + %res = tuple () + return %res : $() +} + sil_global @staticProp: $Int // CHECK-LABEL: sil private @globalinit_func0 : $@convention(thin) () -> () { diff --git a/test/SIL/Serialization/borrow.sil b/test/SIL/Serialization/borrow.sil index cdb8725d165f2..0362b1b572c76 100644 --- a/test/SIL/Serialization/borrow.sil +++ b/test/SIL/Serialization/borrow.sil @@ -8,6 +8,40 @@ sil_stage canonical import Builtin +// CHECK-LABEL: sil [serialized] [ossa] @begin_borrow_test +// CHECK: begin_borrow [defined] {{%[^,]+}} +// CHECK: begin_borrow {{%[^,]+}} +// CHECK: } // end sil function 'begin_borrow_test' +sil [serialized] [ossa] @begin_borrow_test : $@convention(thin) () -> () { + %instance = alloc_ref $C + %guaranteed_c = begin_borrow [defined] %instance : $C + end_borrow %guaranteed_c : $C + %guaranteed_c2 = begin_borrow %instance : $C + end_borrow %guaranteed_c2 : $C + destroy_value %instance : $C + %res = tuple () + return %res : $() +} + +// CHECK-LABEL: sil [serialized] [ossa] @alloc_stack_test +// CHECK: alloc_stack $Builtin.NativeObject +// CHECK: alloc_stack [dynamic_lifetime] +// CHECK: alloc_stack [lexical] +// CHECK: alloc_stack [dynamic_lifetime] [lexical] +// CHECK: } // end sil function 'alloc_stack_test' +sil [serialized] [ossa] @alloc_stack_test : $@convention(thin) () -> () { + %instance = alloc_stack $Builtin.NativeObject + dealloc_stack %instance : $*Builtin.NativeObject + %instance2 = alloc_stack [dynamic_lifetime] $Builtin.NativeObject + dealloc_stack %instance2 : $*Builtin.NativeObject + %instance3 = alloc_stack [lexical] $Builtin.NativeObject + dealloc_stack %instance3 : $*Builtin.NativeObject + %instance4 = alloc_stack [lexical] [dynamic_lifetime] $Builtin.NativeObject + dealloc_stack %instance4 : $*Builtin.NativeObject + %res = tuple () + return %res : $() +} + // We do not verify here, but just make sure that all of the combinations parse and print correctly. // CHECK-LABEL: sil [serialized] [ossa] @borrow_test : $@convention(thin) (@in Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () { // CHECK: bb0([[ARG1:%[0-9]+]] : $*Builtin.NativeObject, [[ARG2:%[0-9]+]] : @guaranteed $Builtin.NativeObject): @@ -31,15 +65,3 @@ bb0(%0 : $*Builtin.NativeObject, %1 : @guaranteed $Builtin.NativeObject): } class C {} - -// CHECK-LABEL: sil [ossa] @defined_borrow_test -// CHECK: begin_borrow [defined] {{%[^,]+}} -// CHECK-LABEL: } // end sil function 'defined_borrow_test' -sil [ossa] @defined_borrow_test : $@convention(thin) () -> () { - %instance = alloc_ref $C - %guaranteed_c = begin_borrow [defined] %instance : $C - end_borrow %guaranteed_c : $C - destroy_value %instance : $C - %res = tuple () - return %res : $() -} diff --git a/test/SIL/cloning.sil b/test/SIL/cloning.sil index 1f1b84375d812..46c472dd4e313 100644 --- a/test/SIL/cloning.sil +++ b/test/SIL/cloning.sil @@ -45,3 +45,28 @@ sil [ossa] @caller_begin_borrow_defined : $@convention(thin) () -> () { %res = apply %callee_begin_borrow_defined() : $@convention(thin) () -> () return %res : $() } + +sil [ossa] @callee_alloc_stack : $@convention(thin) () -> () { + %instance = alloc_stack $Builtin.NativeObject + dealloc_stack %instance : $*Builtin.NativeObject + %instance2 = alloc_stack [dynamic_lifetime] $Builtin.NativeObject + dealloc_stack %instance2 : $*Builtin.NativeObject + %instance3 = alloc_stack [lexical] $Builtin.NativeObject + dealloc_stack %instance3 : $*Builtin.NativeObject + %instance4 = alloc_stack [dynamic_lifetime] [lexical] $Builtin.NativeObject + dealloc_stack %instance4 : $*Builtin.NativeObject + %res = tuple () + return %res : $() +} + +// CHECK-LABEL: sil [ossa] @caller_alloc_stack_lexical +// CHECK: alloc_stack +// CHECK: alloc_stack [dynamic_lifetime] +// CHECK: alloc_stack [lexical] +// CHECK: alloc_stack [dynamic_lifetime] [lexical] +// CHECK-LABEL: } // end sil function 'caller_alloc_stack_lexical' +sil [ossa] @caller_alloc_stack_lexical : $@convention(thin) () -> () { + %callee_alloc_stack = function_ref @callee_alloc_stack : $@convention(thin) () -> () + %res = apply %callee_alloc_stack() : $@convention(thin) () -> () + return %res : $() +} diff --git a/test/SILGen/borrow.swift b/test/SILGen/borrow.swift index 6616d8d3fc4d9..a858ecd8176fe 100644 --- a/test/SILGen/borrow.swift +++ b/test/SILGen/borrow.swift @@ -1,5 +1,5 @@ -// RUN: %target-swift-emit-silgen -module-name borrow -parse-stdlib %s | %FileCheck %s +// RUN: %target-swift-emit-silgen -enable-experimental-defined-lifetimes -module-name borrow -parse-stdlib %s | %FileCheck %s import Swift @@ -8,9 +8,12 @@ final class D {} // Make sure that we insert the borrow for a ref_element_addr lvalue in the // proper place. final class C { + init() {} + init?(failably: ()) {} var d: D = D() } +func use(_ t: T) {} func useD(_ d: D) {} // CHECK-LABEL: sil hidden [ossa] @$s6borrow44lvalueBorrowShouldBeAtEndOfFormalAccessScope{{.*}} : $@convention(thin) () -> () { @@ -33,3 +36,58 @@ func lvalueBorrowShouldBeAtEndOfFormalAccessScope() { var c = C() useD(c.d) } + +// CHECK-LABEL: sil hidden [ossa] @defined_borrow_let_class +// CHECK: [[INIT_C:%[^,]+]] = function_ref @$s6borrow1CCACycfC +// CHECK: [[INSTANCE:%[^,]+]] = apply [[INIT_C]]({{%[0-9]+}}) +// CHECK: [[BORROW:%[^,]+]] = begin_borrow [defined] [[INSTANCE]] : $C +// CHECK: end_borrow [[BORROW:%[^,]+]] +// CHECK-LABEL: } // end sil function 'defined_borrow_let_class' +@_silgen_name("defined_borrow_let_class") +func defined_borrow_let_class() { + let c = C() +} + +// CHECK-LABEL: sil hidden [ossa] @defined_borrow_if_let_class +// CHECK: [[INIT_C:%[^,]+]] = function_ref @$s6borrow1CC8failablyACSgyt_tcfC +// CHECK: [[INSTANCE:%[^,]+]] = apply [[INIT_C]]({{%[^,]+}}) +// CHECK: switch_enum [[INSTANCE]] : $Optional, case #Optional.some!enumelt: [[BASIC_BLOCK2:bb[^,]+]], case #Optional.none!enumelt: {{bb[^,]+}} +// CHECK: [[BASIC_BLOCK2]]([[INSTANCE:%[^,]+]] : @owned $C): +// CHECK: [[BORROW:%[^,]+]] = begin_borrow [defined] [[INSTANCE]] : $C +// CHECK: end_borrow [[BORROW]] : $C +// CHECK-LABEL: // end sil function 'defined_borrow_if_let_class' +@_silgen_name("defined_borrow_if_let_class") +func defined_borrow_if_let_class() { + if let c = C(failably: ()) { + use(()) + } +} + +struct S { + let c: C +} + +// CHECK-LABEL: sil hidden [ossa] @defined_borrow_let_class_in_struct +// CHECK: [[INIT_S:%[^,]+]] = function_ref @$s6borrow1SV1cAcA1CC_tcfC +// CHECK: [[INSTANCE:%[^,]+]] = apply [[INIT_S]]({{%[0-9]+}}, {{%[0-9]+}}) +// CHECK: [[BORROW:%[^,]+]] = begin_borrow [defined] [[INSTANCE]] : $S +// CHECK: end_borrow [[BORROW:%[^,]+]] +// CHECK-LABEL: } // end sil function 'defined_borrow_let_class_in_struct' +@_silgen_name("defined_borrow_let_class_in_struct") +func defined_borrow_let_class_in_struct() { + let s = S(c: C()) +} + +enum E { + case e(C) +} + +// CHECK-LABEL: sil hidden [ossa] @defined_borrow_let_class_in_enum +// CHECK: [[INSTANCE:%[^,]+]] = enum $E, #E.e!enumelt, {{%[0-9]+}} : $C +// CHECK: [[BORROW:%[^,]+]] = begin_borrow [defined] [[INSTANCE]] : $E +// CHECK: end_borrow [[BORROW:%[^,]+]] +// CHECK-LABEL: } // end sil function 'defined_borrow_let_class_in_enum' +@_silgen_name("defined_borrow_let_class_in_enum") +func defined_borrow_let_class_in_enum() { + let s = E.e(C()) +} diff --git a/test/SILGen/sil_verifier_method_self_type.swift b/test/SILGen/sil_verifier_method_self_type.swift new file mode 100644 index 0000000000000..173302307edb0 --- /dev/null +++ b/test/SILGen/sil_verifier_method_self_type.swift @@ -0,0 +1,11 @@ +// RUN: %target-swift-emit-silgen %s -requirement-machine=verify + +public class C { + public func method() -> Value { fatalError() } +} + +public func foo(_: () -> T) {} + +public func bar() { + foo { C().method() } +} diff --git a/test/SILGen/type_lowering_subst_function_type_conditional_conformance.swift b/test/SILGen/type_lowering_subst_function_type_conditional_conformance.swift new file mode 100644 index 0000000000000..1910aa0b8dd8e --- /dev/null +++ b/test/SILGen/type_lowering_subst_function_type_conditional_conformance.swift @@ -0,0 +1,53 @@ +// RUN: %target-swift-emit-silgen %s -requirement-machine=verify | %FileCheck %s + +enum E { + case a(T.X) +} + +struct S {} + +protocol P { + associatedtype X +} + +extension S : P where T : P { + typealias X = T.X +} + +func foo(_ x: E>) { +// Ensure that the lowered substituted SIL function type for `() -> E>` +// preserves the T: P constraint necessary to allow for `S` to substitute +// into `E` + bar({ return x }) +} + +// CHECK-LABEL: {{^}}sil {{.*}} @${{.*}}3bar +// CHECK-SAME: @substituted <τ_0_0 where τ_0_0 : P> () -> @out E> for +func bar(_: () -> E>) {} + +// --- + +protocol Q: P { + associatedtype Y +} + +enum E2 { + case a(T.Y) +} + +struct S2: P { + typealias X = T.X +} + +extension S2: Q where T: Q { + typealias Y = T.Y +} + +func foo2(_ x: E2>) { + bar2({ return x }) +} + +// CHECK-LABEL: {{^}}sil {{.*}} @${{.*}}4bar2 +// CHECK-SAME: @substituted <τ_0_0 where τ_0_0 : Q> () -> @out E2> for +func bar2(_: () -> E2>) {} + diff --git a/test/Serialization/restrict-swiftmodule-to-sdk.swift b/test/Serialization/restrict-swiftmodule-to-sdk.swift new file mode 100644 index 0000000000000..5c678fe70a3a8 --- /dev/null +++ b/test/Serialization/restrict-swiftmodule-to-sdk.swift @@ -0,0 +1,20 @@ +// RUN: %empty-directory(%t/cache) +// RUN: %empty-directory(%t/build) +// RUN: %{python} %utils/split_file.py -o %t %s + +/// Build Lib against SDK A. +// RUN: %target-swift-frontend -emit-module %t/Lib.swift -swift-version 5 -target-sdk-name A -o %t/build -parse-stdlib -module-cache-path %t/cache + +/// Building Client against SDK A should work fine as expected. +// RUN: %target-swift-frontend -typecheck %t/Client.swift -swift-version 5 -target-sdk-name A -I %t/build -parse-stdlib -module-cache-path %t/cache + +/// Build Client against SDK B, this should fail at loading Lib against a different SDK than A. +// RUN: not %target-swift-frontend -typecheck %t/Client.swift -swift-version 5 -target-sdk-name B -I %t/build -parse-stdlib -module-cache-path %t/cache 2>&1 | %FileCheck %s +// CHECK: cannot load module 'Lib' built with SDK 'A' when using SDK 'B': {{.*}}Lib.swiftmodule + +// BEGIN Lib.swift +public func foo() {} + +// BEGIN Client.swift +import Lib +foo() diff --git a/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface b/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface index 04fba0eeed4da..851f24ce52b03 100644 --- a/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface +++ b/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface @@ -1,7 +1,6 @@ // swift-interface-format-version: 1.0 // swift-tools-version: Apple Swift version 5.1 (swiftlang-1100.0.38 clang-1100.0.20.14) -// swift-module-flags: -target arm64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo -import Swift +// swift-module-flags: -target arm64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo -parse-stdlib public class RemovedClass { @objc deinit } diff --git a/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/x86_64-apple-macos.swiftinterface b/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/x86_64-apple-macos.swiftinterface index 5dd2912092b75..616271689153f 100644 --- a/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/x86_64-apple-macos.swiftinterface +++ b/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/x86_64-apple-macos.swiftinterface @@ -1,7 +1,6 @@ // swift-interface-format-version: 1.0 // swift-tools-version: Apple Swift version 5.1 (swiftlang-1100.0.38 clang-1100.0.20.14) -// swift-module-flags: -target x86_64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo -import Swift +// swift-module-flags: -target x86_64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo -parse-stdlib public class RemovedClass { @objc deinit } diff --git a/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface b/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface index 606b8bd222422..f20e4f4217a6c 100644 --- a/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface +++ b/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface @@ -1,7 +1,6 @@ // swift-interface-format-version: 1.0 // swift-tools-version: Apple Swift version 5.1 (swiftlang-1100.0.38 clang-1100.0.20.14) -// swift-module-flags: -target arm64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo -import Swift +// swift-module-flags: -target arm64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo -parse-stdlib public class AddedClass { @objc deinit } diff --git a/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/x86_64-apple-macos.swiftinterface b/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/x86_64-apple-macos.swiftinterface index 3bc9676211a66..5315e1537ee54 100644 --- a/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/x86_64-apple-macos.swiftinterface +++ b/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/x86_64-apple-macos.swiftinterface @@ -1,7 +1,6 @@ // swift-interface-format-version: 1.0 // swift-tools-version: Apple Swift version 5.1 (swiftlang-1100.0.38 clang-1100.0.20.14) -// swift-module-flags: -target x86_64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo -import Swift +// swift-module-flags: -target x86_64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo -parse-stdlib public class AddedClass { @objc deinit } diff --git a/test/api-digester/stability-stdlib-abi-without-asserts.test b/test/api-digester/stability-stdlib-abi-without-asserts.test index 4006a88b676d9..9b731bbf42fb1 100644 --- a/test/api-digester/stability-stdlib-abi-without-asserts.test +++ b/test/api-digester/stability-stdlib-abi-without-asserts.test @@ -50,11 +50,6 @@ Func _prespecialize() is a new API without @available attribute Func _stdlib_isOSVersionAtLeastOrVariantVersionAtLeast(_:_:_:_:_:_:) is a new API without @available attribute -// These reflection APIs are exposed to facilitate building SwiftReflectionTest.swift when testing Release builds. -Func _getMetadataSection(_:) is a new API without @available attribute -Func _getMetadataSectionCount() is a new API without @available attribute -Func _getMetadataSectionName(_:) is a new API without @available attribute - Func Collection.removingSubranges(_:) has been removed Func Collection.subranges(of:) has been removed Func Collection.subranges(where:) has been removed diff --git a/test/stdlib/Reflection_objc.swift b/test/stdlib/Reflection_objc.swift index 2e8d2fe437580..4733531e94283 100644 --- a/test/stdlib/Reflection_objc.swift +++ b/test/stdlib/Reflection_objc.swift @@ -12,6 +12,9 @@ // UNSUPPORTED: use_os_stdlib // UNSUPPORTED: back_deployment_runtime +// Disabled arm64e for now since it is failing +// XFAIL: CPU=arm64e + // // DO NOT add more tests to this file. Add them to test/1_stdlib/Runtime.swift. //