Skip to content

Commit ae9238e

Browse files
committed
Introduce an assertion configuration for "release with bounds safety"
To support the introduction of bounds checks for the unsafe buffer pointer types, introduce a new assertion confirmation that is for release builds that also have this buffer safety. It can be enabled with the experimental feature `UnsafePointerBoundsSafety` in normal builds, or (for testing) the `ReleaseWithBoundsSafety` assert configuration. The end goal of this approach to change the experimental feature to an upcoming feature, which will also enabled with Swift 6.
1 parent fcec8b5 commit ae9238e

File tree

13 files changed

+72
-14
lines changed

13 files changed

+72
-14
lines changed

include/swift/AST/SILOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class SILOptions {
198198
Debug = 0, // Enables all asserts.
199199
Release = 1, // Disables asserts.
200200
Unchecked = 2, // Disables asserts, preconditions, and runtime checks.
201+
ReleaseWithBoundsSafety = 3, // Enables all asserts + bounds checks for unsafe pointers
201202

202203
// Leave the assert_configuration instruction around.
203204
DisableReplacement = UINT_MAX

include/swift/Basic/Features.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ UPCOMING_FEATURE(FullTypedThrows, 413, 6)
129129

130130
UPCOMING_FEATURE(ExistentialAny, 335, 7)
131131

132+
EXPERIMENTAL_FEATURE(UnsafePointerBoundsSafety, true)
133+
132134
EXPERIMENTAL_FEATURE(StaticAssert, false)
133135
EXPERIMENTAL_FEATURE(NamedOpaqueTypes, false)
134136
EXPERIMENTAL_FEATURE(FlowSensitiveConcurrencyCaptures, false)

include/swift/Option/Options.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ def debug_info_store_invocation : Flag<["-"], "debug-info-store-invocation">,
10551055
def AssertConfig : Separate<["-"], "assert-config">,
10561056
Flags<[FrontendOption, ModuleInterfaceOption]>,
10571057
HelpText<"Specify the assert_configuration replacement. "
1058-
"Possible values are Debug, Release, Unchecked, DisableReplacement.">;
1058+
"Possible values are Debug, Release, Unchecked, ReleaseWithBoundsSafety, DisableReplacement.">;
10591059

10601060
// Code formatting options
10611061

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ struct BridgedPassContext {
298298
enum class AssertConfiguration {
299299
Debug = 0,
300300
Release = 1,
301-
Unchecked = 2
301+
Unchecked = 2,
302+
ReleaseWithBoundsSafety = 3,
302303
};
303304

304305
BRIDGED_INLINE bool enableStackProtection() const;

include/swift/SILOptimizer/OptimizerBridgingImpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ static_assert((int)BridgedPassContext::SILStage::Lowered == (int)swift::SILStage
443443
static_assert((int)BridgedPassContext::AssertConfiguration::Debug == (int)swift::SILOptions::Debug);
444444
static_assert((int)BridgedPassContext::AssertConfiguration::Release == (int)swift::SILOptions::Release);
445445
static_assert((int)BridgedPassContext::AssertConfiguration::Unchecked == (int)swift::SILOptions::Unchecked);
446+
static_assert((int)BridgedPassContext::AssertConfiguration::ReleaseWithBoundsSafety == (int)swift::SILOptions::ReleaseWithBoundsSafety);
446447

447448
SWIFT_END_NULLABILITY_ANNOTATIONS
448449

lib/AST/ASTPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3940,6 +3940,10 @@ static bool usesFeaturePreconcurrencyConformances(Decl *decl) {
39403940

39413941
static bool usesFeatureBorrowingSwitch(Decl *decl) { return false; }
39423942

3943+
static bool usesFeatureUnsafePointerBoundsSafety(Decl *decl) {
3944+
return false;
3945+
}
3946+
39433947
/// Suppress the printing of a particular feature.
39443948
static void suppressingFeature(PrintOptions &options, Feature feature,
39453949
llvm::function_ref<void()> action) {

lib/ASTGen/Sources/ASTGen/Macros.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ func findSyntaxNodeInSourceFile<Node: SyntaxProtocol>(
608608

609609
let sourceFilePtr = sourceFilePtr.assumingMemoryBound(to: ExportedSourceFile.self)
610610

611-
// Find the offset.
611+
// Find the offset in this buffer.
612612
let buffer = sourceFilePtr.pointee.buffer
613613
let offset = sourceLocationPtr - buffer.baseAddress!
614614
if offset < 0 || offset >= buffer.count {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,7 @@ void parseExclusivityEnforcementOptions(const llvm::opt::Arg *A,
20232023

20242024
static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
20252025
IRGenOptions &IRGenOpts,
2026+
const LangOptions &LangOpts,
20262027
const FrontendOptions &FEOpts,
20272028
const TypeCheckerOptions &TCOpts,
20282029
DiagnosticEngine &Diags,
@@ -2111,6 +2112,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
21112112
Opts.AssertConfig = SILOptions::Release;
21122113
} else if (Configuration == "Unchecked") {
21132114
Opts.AssertConfig = SILOptions::Unchecked;
2115+
} else if (Configuration == "ReleaseWithBoundsSafety") {
2116+
Opts.AssertConfig = SILOptions::ReleaseWithBoundsSafety;
21142117
} else {
21152118
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
21162119
A->getAsString(Args), A->getValue());
@@ -2124,7 +2127,11 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
21242127
// Set the assert configuration according to the optimization level if it
21252128
// has not been set by the -Ounchecked flag.
21262129
Opts.AssertConfig =
2127-
(IRGenOpts.shouldOptimize() ? SILOptions::Release : SILOptions::Debug);
2130+
IRGenOpts.shouldOptimize()
2131+
? (LangOpts.hasFeature(Feature::UnsafePointerBoundsSafety)
2132+
? SILOptions::ReleaseWithBoundsSafety
2133+
: SILOptions::Release)
2134+
: SILOptions::Debug;
21282135
}
21292136

21302137
// -Ounchecked might also set removal of runtime asserts (cond_fail).
@@ -3193,7 +3200,7 @@ bool CompilerInvocation::parseArgs(
31933200
return true;
31943201
}
31953202

3196-
if (ParseSILArgs(SILOpts, ParsedArgs, IRGenOpts, FrontendOpts,
3203+
if (ParseSILArgs(SILOpts, ParsedArgs, IRGenOpts, LangOpts, FrontendOpts,
31973204
TypeCheckerOpts, Diags,
31983205
LangOpts.Target, ClangImporterOpts)) {
31993206
return true;

stdlib/public/Concurrency/ExecutorAssertions.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ extension SerialExecutor {
5353
_ message: @autoclosure () -> String = String(),
5454
file: StaticString = #fileID, line: UInt = #line
5555
) {
56-
guard _isDebugAssertConfiguration() || _isReleaseAssertConfiguration() else {
56+
guard _isDebugAssertConfiguration() || _isReleaseAssertConfiguration() ||
57+
_isReleaseAssertWithBoundsSafetyConfiguration() else {
5758
return
5859
}
5960

@@ -102,7 +103,8 @@ extension Actor {
102103
_ message: @autoclosure () -> String = String(),
103104
file: StaticString = #fileID, line: UInt = #line
104105
) {
105-
guard _isDebugAssertConfiguration() || _isReleaseAssertConfiguration() else {
106+
guard _isDebugAssertConfiguration() || _isReleaseAssertConfiguration() ||
107+
_isReleaseAssertWithBoundsSafetyConfiguration() else {
106108
return
107109
}
108110

stdlib/public/Distributed/DistributedAssertions.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ extension DistributedActor {
4747
_ message: @autoclosure () -> String = String(),
4848
file: StaticString = #fileID, line: UInt = #line
4949
) {
50-
guard _isDebugAssertConfiguration() || _isReleaseAssertConfiguration() else {
50+
guard _isDebugAssertConfiguration() || _isReleaseAssertConfiguration() ||
51+
_isReleaseAssertWithBoundsSafetyConfiguration() else {
5152
return
5253
}
5354

0 commit comments

Comments
 (0)