Skip to content

Commit

Permalink
[Exclusivity] Put suppression for free function swap() behind a flag
Browse files Browse the repository at this point in the history
And leave suppression off by default for now. We'll use this to evaluate
how often swap() causes exclusivity conflicts to be reported.
  • Loading branch information
devincoughlin committed Apr 19, 2017
1 parent 6d35d32 commit ae3b13e
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 29 deletions.
4 changes: 4 additions & 0 deletions include/swift/AST/SILOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ class SILOptions {
/// Emit compile-time diagnostics when the law of exclusivity is violated.
bool EnforceExclusivityStatic = false;

/// Suppress static diagnostics for violations of exclusive access for calls
/// to the Standard Library's swap() free function.
bool SuppressStaticExclusivitySwap = false;

/// Emit checks to trap at run time when the law of exclusivity is violated.
bool EnforceExclusivityDynamic = false;

Expand Down
3 changes: 3 additions & 0 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ def disable_mandatory_semantic_arc_opts : Flag<["-"], "disable-mandatory-semanti
def assume_parsing_unqualified_ownership_sil : Flag<["-"], "assume-parsing-unqualified-ownership-sil">,
HelpText<"Assume unqualified SIL ownership when parsing SIL">;

def suppress_static_exclusivity_swap : Flag<["-"], "suppress-static-exclusivity-swap">,
HelpText<"Suppress static violations of exclusive access with swap()">;

def enable_sil_opaque_values : Flag<["-"], "enable-sil-opaque-values">,
HelpText<"Enable SIL Opaque Values">;

Expand Down
2 changes: 2 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1324,6 +1324,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
|= Args.hasArg(OPT_assume_parsing_unqualified_ownership_sil);
Opts.EnableMandatorySemanticARCOpts |=
!Args.hasArg(OPT_disable_mandatory_semantic_arc_opts);
Opts.SuppressStaticExclusivitySwap |=
Args.hasArg(OPT_suppress_static_exclusivity_swap);

if (Args.hasArg(OPT_debug_on_sil)) {
// Derive the name of the SIL file for debugging from
Expand Down
3 changes: 2 additions & 1 deletion lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,8 @@ static void checkStaticExclusivity(SILFunction &Fn, PostOrderFunctionInfo *PO) {
if (auto *AI = dyn_cast<ApplyInst>(&I)) {
// Suppress for the arguments to the Standard Library's swap()
// function until we can recommend a safe alternative.
if (isCallToStandardLibrarySwap(AI, Fn.getASTContext()))
if (Fn.getModule().getOptions().SuppressStaticExclusivitySwap &&
isCallToStandardLibrarySwap(AI, Fn.getASTContext()))
CallsToSuppress.push_back(AI);
}

Expand Down
30 changes: 2 additions & 28 deletions test/SILOptimizer/exclusivity_static_diagnostics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,10 @@ func simpleInoutDiagnostic() {
}


func swapSuppression(_ i: Int, _ j: Int) {
func swapNoSuppression(_ i: Int, _ j: Int) {
var a: [Int] = [1, 2, 3]

swap(&a[i], &a[j]) // no-warning

// expected-warning@+2{{modification requires exclusive access}}
// expected-note@+1{{conflicting modification requires exclusive access}}
takesTwoInouts(&a[i], &a[j])
}

func missedSwapSuppression(_ i: Int, _ j: Int) {
var a: [Int] = [1, 2, 3]

// We don't suppress when swap() is used as a value
let mySwap: (inout Int, inout Int) -> () = swap

// expected-warning@+2{{modification requires exclusive access}}
// expected-note@+1{{conflicting modification requires exclusive access}}
mySwap(&a[i], &a[j])
}

func dontSuppressUserSwap(_ i: Int, _ j: Int) {
var a: [Int] = [1, 2, 3]

// Don't suppress on user-defined swap.
func swap<T>(_ p1: inout T, _ p2: inout T) {
return (p1, p2) = (p2, p1)
}

// expected-warning@+2{{modification requires exclusive access}}
// expected-note@+1{{conflicting modification requires exclusive access}}
swap(&a[i], &a[j])
swap(&a[i], &a[j]) // no-warning
}
39 changes: 39 additions & 0 deletions test/SILOptimizer/exclusivity_suppress_swap.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// RUN: %target-swift-frontend -enforce-exclusivity=checked -suppress-static-exclusivity-swap -emit-sil -primary-file %s -o /dev/null -verify

import Swift

func takesTwoInouts(_ p1: inout Int, _ p2: inout Int) { }

func swapSuppression(_ i: Int, _ j: Int) {
var a: [Int] = [1, 2, 3]

swap(&a[i], &a[j]) // no-warning

// expected-warning@+2{{modification requires exclusive access}}
// expected-note@+1{{conflicting modification requires exclusive access}}
takesTwoInouts(&a[i], &a[j])
}

func missedSwapSuppression(_ i: Int, _ j: Int) {
var a: [Int] = [1, 2, 3]

// We don't suppress when swap() is used as a value
let mySwap: (inout Int, inout Int) -> () = swap

// expected-warning@+2{{modification requires exclusive access}}
// expected-note@+1{{conflicting modification requires exclusive access}}
mySwap(&a[i], &a[j])
}

func dontSuppressUserSwap(_ i: Int, _ j: Int) {
var a: [Int] = [1, 2, 3]

// Don't suppress on user-defined swap.
func swap<T>(_ p1: inout T, _ p2: inout T) {
return (p1, p2) = (p2, p1)
}

// expected-warning@+2{{modification requires exclusive access}}
// expected-note@+1{{conflicting modification requires exclusive access}}
swap(&a[i], &a[j])
}

0 comments on commit ae3b13e

Please sign in to comment.