Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ Note: This is in reverse chronological order, so newer entries are added to the
Swift Next
-----------

Swift 6.2
---------

* [#8314]

Starting from tools-version 6.2, `SwiftSetting` provides a `strictMemorySafety` setting to enable the strict memory safety checking introduced in [SE-0458].

Swift 6.0
-----------

Expand Down Expand Up @@ -393,7 +400,7 @@ Swift 3.0
[SE-0387]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0387-cross-compilation-destinations.md
[SE-0391]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0391-package-registry-publish.md
[SE-0387 proposal text]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0387-cross-compilation-destinations.md#swift-sdk-installation-and-configuration

[SE-0458]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0458-strict-memory-safety.md
[SR-5918]: https://bugs.swift.org/browse/SR-5918
[SR-6978]: https://bugs.swift.org/browse/SR-6978
[SR-13566]: https://bugs.swift.org/browse/SR-13566
Expand Down
12 changes: 11 additions & 1 deletion Sources/Build/BuildDescription/ProductBuildDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -283,16 +283,26 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
// Pass experimental features to link jobs in addition to compile jobs. Preserve ordering while eliminating
// duplicates with `OrderedSet`.
var experimentalFeatures = OrderedSet<String>()
var strictMemorySafety = false
for target in self.product.modules {
let swiftSettings = target.underlying.buildSettingsDescription.filter { $0.tool == .swift }
for case let .enableExperimentalFeature(feature) in swiftSettings.map(\.kind) {
for kind in swiftSettings.map(\.kind) {
if case let .enableExperimentalFeature(feature) = kind {
experimentalFeatures.append(feature)
} else if kind == .strictMemorySafety {
strictMemorySafety = true
}
}
}

for feature in experimentalFeatures {
args += ["-enable-experimental-feature", feature]
}

if strictMemorySafety {
args.append("-strict-memory-safety")
}

// Embed the swift stdlib library path inside tests and executables on Darwin.
let useStdlibRpath: Bool
switch self.product.type {
Expand Down
22 changes: 22 additions & 0 deletions Sources/PackageDescription/BuildSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,28 @@ public struct SwiftSetting: Sendable {
name: "enableExperimentalFeature", value: [name], condition: condition)
}

/// Enable strict memory safety checking.
///
/// Strict memory safety checking is an opt-in compiler feature that
/// identifies any uses of language constructs or APIs that break
/// memory safety. Issues are reported as warnings and can generally
/// be suppressed by adding annotations (such as `@unsafe` and `unsafe`)
/// that acknowledge the presence of unsafe code, making it easier to
/// review and audit at a later time.
///
/// - Since: First available in PackageDescription 6.2.
///
/// - Parameters:
/// - condition: A condition that restricts the application of the build
/// setting.
@available(_PackageDescription, introduced: 6.2)
public static func strictMemorySafety(
_ condition: BuildSettingCondition? = nil
) -> SwiftSetting {
return SwiftSetting(
name: "strictMemorySafety", value: ["ON"], condition: condition)
}

public enum InteroperabilityMode: String {
case C
case Cxx
Expand Down
2 changes: 2 additions & 0 deletions Sources/PackageLoading/ManifestJSONParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,8 @@ extension TargetBuildSettingDescription.Kind {
throw InternalError("invalid (empty) build settings value")
}
return .enableExperimentalFeature(value)
case "strictMemorySafety":
return .strictMemorySafety
case "unsafeFlags":
return .unsafeFlags(values)

Expand Down
13 changes: 13 additions & 0 deletions Sources/PackageLoading/PackageBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,19 @@ public final class PackageBuilder {

values = ["-enable-experimental-feature", value]

case .strictMemorySafety:
switch setting.tool {
case .c, .cxx, .linker:
throw InternalError(
"only Swift supports strict memory safety"
)

case .swift:
decl = .OTHER_SWIFT_FLAGS
}

values = ["-strict-memory-safety"]

case .swiftLanguageMode(let version):
switch setting.tool {
case .c, .cxx, .linker:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public enum TargetBuildSettingDescription {

case enableUpcomingFeature(String)
case enableExperimentalFeature(String)
case strictMemorySafety

case unsafeFlags([String])

Expand All @@ -47,7 +48,7 @@ public enum TargetBuildSettingDescription {
// If `.unsafeFlags` is used, but doesn't specify any flags, we treat it the same way as not specifying it.
return !flags.isEmpty
case .headerSearchPath, .define, .linkedLibrary, .linkedFramework, .interoperabilityMode,
.enableUpcomingFeature, .enableExperimentalFeature, .swiftLanguageMode:
.enableUpcomingFeature, .enableExperimentalFeature, .strictMemorySafety, .swiftLanguageMode:
return false
}
}
Expand Down
4 changes: 4 additions & 0 deletions Sources/PackageModel/ManifestSourceGeneration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ fileprivate extension SourceCodeFragment {
params.append(SourceCodeFragment(from: condition))
}
self.init(enum: setting.kind.name, subnodes: params)
case .strictMemorySafety:
self.init(enum: setting.kind.name, subnodes: [])
case .define(let value):
let parts = value.split(separator: "=", maxSplits: 1)
assert(parts.count == 1 || parts.count == 2)
Expand Down Expand Up @@ -686,6 +688,8 @@ extension TargetBuildSettingDescription.Kind {
return "enableUpcomingFeature"
case .enableExperimentalFeature:
return "enableExperimentalFeature"
case .strictMemorySafety:
return "strictMemorySafety"
case .swiftLanguageMode:
return "swiftLanguageMode"
}
Expand Down
1 change: 1 addition & 0 deletions Sources/PackageModel/ToolsVersion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public struct ToolsVersion: Equatable, Hashable, Codable, Sendable {
public static let v5_10 = ToolsVersion(version: "5.10.0")
public static let v6_0 = ToolsVersion(version: "6.0.0")
public static let v6_1 = ToolsVersion(version: "6.1.0")
public static let v6_2 = ToolsVersion(version: "6.2.0")
public static let vNext = ToolsVersion(version: "999.0.0")

/// The current tools version in use.
Expand Down
5 changes: 5 additions & 0 deletions Tests/BuildTests/BuildPlanTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4247,6 +4247,7 @@ final class BuildPlanTests: XCTestCase {
kind: .enableUpcomingFeature("WorstFeature"),
condition: .init(platformNames: ["macos"], config: "debug")
),
.init(tool: .swift, kind: .strictMemorySafety),
]
),
TargetDescription(
Expand Down Expand Up @@ -4371,6 +4372,7 @@ final class BuildPlanTests: XCTestCase {
"-cxx-interoperability-mode=default",
"-Xcc", "-std=c++17",
"-enable-upcoming-feature", "BestFeature",
"-strict-memory-safety",
"-g",
"-Xcc", "-g",
"-Xcc", "-fno-omit-frame-pointer",
Expand Down Expand Up @@ -4435,6 +4437,7 @@ final class BuildPlanTests: XCTestCase {
"-Xcc", "-std=c++17",
"-enable-upcoming-feature",
"BestFeature",
"-strict-memory-safety",
"-g",
"-Xcc", "-g",
"-Xcc", "-fomit-frame-pointer",
Expand Down Expand Up @@ -4490,6 +4493,7 @@ final class BuildPlanTests: XCTestCase {
"-Xcc", "-std=c++17",
"-enable-upcoming-feature",
"BestFeature",
"-strict-memory-safety",
"-g",
"-Xcc", "-g",
"-Xcc", "-fno-omit-frame-pointer",
Expand Down Expand Up @@ -4534,6 +4538,7 @@ final class BuildPlanTests: XCTestCase {
"-Xcc", "-std=c++17",
"-enable-upcoming-feature", "BestFeature",
"-enable-upcoming-feature", "WorstFeature",
"-strict-memory-safety",
"-g",
"-Xcc", "-g",
.end,
Expand Down
20 changes: 20 additions & 0 deletions Tests/WorkspaceTests/ManifestSourceGenerationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,26 @@ final class ManifestSourceGenerationTests: XCTestCase {
try await testManifestWritingRoundTrip(manifestContents: manifestContents, toolsVersion: .v5_8)
}

func testStrictMemorySafety() async throws {
let manifestContents = """
// swift-tools-version:6.2
import PackageDescription

let package = Package(
name: "UpcomingAndExperimentalFeatures",
targets: [
.target(
name: "MyTool",
swiftSettings: [
.strictMemorySafety(),
]
),
]
)
"""
try await testManifestWritingRoundTrip(manifestContents: manifestContents, toolsVersion: .v6_2)
}

func testPluginNetworkingPermissionGeneration() async throws {
let manifest = Manifest.createRootManifest(
displayName: "thisPkg",
Expand Down