Skip to content

Commit ab25084

Browse files
committed
Downgrade dynamic exclusivity failures to a warning in Swift 3 compatibility mode.
1 parent e01c31a commit ab25084

File tree

6 files changed

+75
-17
lines changed

6 files changed

+75
-17
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,12 +570,28 @@ class FieldType {
570570
enum class ExclusivityFlags : uintptr_t {
571571
Read = 0x0,
572572
Modify = 0x1,
573-
ActionMask = 0x1
573+
// Leave space for other actions.
574+
// Don't rely on ActionMask in stable ABI.
575+
ActionMask = 0x1,
576+
577+
// Downgrade exclusivity failures to a warning.
578+
WarningOnly = 0x10
574579
};
580+
static inline ExclusivityFlags operator|(ExclusivityFlags lhs,
581+
ExclusivityFlags rhs) {
582+
return ExclusivityFlags(uintptr_t(lhs) | uintptr_t(rhs));
583+
}
584+
static inline ExclusivityFlags &operator|=(ExclusivityFlags &lhs,
585+
ExclusivityFlags rhs) {
586+
return (lhs = (lhs | rhs));
587+
}
575588
static inline ExclusivityFlags getAccessAction(ExclusivityFlags flags) {
576589
return ExclusivityFlags(uintptr_t(flags)
577590
& uintptr_t(ExclusivityFlags::ActionMask));
578591
}
592+
static inline bool isWarningOnly(ExclusivityFlags flags) {
593+
return uintptr_t(flags) & uintptr_t(ExclusivityFlags::WarningOnly);
594+
}
579595

580596
} // end namespace swift
581597

lib/IRGen/IRGenSIL.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3952,7 +3952,7 @@ void IRGenSILFunction::visitProjectBoxInst(swift::ProjectBoxInst *i) {
39523952
}
39533953
}
39543954

3955-
static ExclusivityFlags getExclusivityFlags(SILAccessKind kind) {
3955+
static ExclusivityFlags getExclusivityAction(SILAccessKind kind) {
39563956
switch (kind) {
39573957
case SILAccessKind::Read:
39583958
return ExclusivityFlags::Read;
@@ -3965,9 +3965,20 @@ static ExclusivityFlags getExclusivityFlags(SILAccessKind kind) {
39653965
llvm_unreachable("bad access kind");
39663966
}
39673967

3968+
static ExclusivityFlags getExclusivityFlags(SILModule &M,
3969+
SILAccessKind kind) {
3970+
auto flags = getExclusivityAction(kind);
3971+
3972+
// In old Swift compatibility modes, downgrade this to a warning.
3973+
if (M.getASTContext().LangOpts.isSwiftVersion3())
3974+
flags |= ExclusivityFlags::WarningOnly;
3975+
3976+
return flags;
3977+
}
3978+
39683979
template <class Inst>
39693980
static ExclusivityFlags getExclusivityFlags(Inst *i) {
3970-
return getExclusivityFlags(i->getAccessKind());
3981+
return getExclusivityFlags(i->getModule(), i->getAccessKind());
39713982
}
39723983

39733984
void IRGenSILFunction::visitBeginAccessInst(BeginAccessInst *access) {

stdlib/public/runtime/Exclusivity.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/Runtime/Exclusivity.h"
2020
#include "swift/Runtime/Metadata.h"
2121
#include <memory>
22+
#include <stdio.h>
2223

2324
// Pick an implementation strategy.
2425
#ifndef SWIFT_EXCLUSIVITY_USE_THREADLOCAL
@@ -61,8 +62,37 @@ static const char *getAccessName(ExclusivityFlags flags) {
6162
switch (flags) {
6263
case ExclusivityFlags::Read: return "read";
6364
case ExclusivityFlags::Modify: return "modify";
65+
default: return "unknown";
6466
}
65-
return "unknown";
67+
}
68+
69+
static void reportExclusivityConflict(ExclusivityFlags oldAction, void *oldPC,
70+
ExclusivityFlags newFlags, void *newPC,
71+
void *pointer) {
72+
// TODO: print something about where the pointer came from?
73+
// TODO: if we do something more computationally intense here,
74+
// suppress warnings if the total warning count exceeds some limit
75+
76+
if (isWarningOnly(newFlags)) {
77+
fprintf(stderr,
78+
"WARNING: %s/%s access conflict detected on address %p\n"
79+
" first access started at PC=%p\n"
80+
" second access started at PC=%p\n",
81+
getAccessName(oldAction),
82+
getAccessName(getAccessAction(newFlags)),
83+
pointer, oldPC, newPC);
84+
return;
85+
}
86+
87+
// TODO: try to recover source-location information from the return
88+
// address.
89+
fatalError(0,
90+
"%s/%s access conflict detected on address %p, aborting\n"
91+
" first access started at PC=%p\n"
92+
" second access started at PC=%p\n",
93+
getAccessName(oldAction),
94+
getAccessName(getAccessAction(newFlags)),
95+
pointer, oldPC, newPC);
6696
}
6797

6898
namespace {
@@ -123,13 +153,11 @@ class AccessSet {
123153
continue;
124154

125155
// Otherwise, it's a conflict.
126-
// TODO: try to recover source-location information from the return
127-
// address.
128-
fatalError(0, "%s(%p) / %s(%p) access conflict detected on address %p,"
129-
" aborting\n",
130-
getAccessName(cur->getAccessAction()), cur->PC,
131-
getAccessName(action), pc,
132-
pointer);
156+
reportExclusivityConflict(cur->getAccessAction(), cur->PC,
157+
flags, pc, pointer);
158+
159+
// If we're only warning, don't report multiple conflicts.
160+
break;
133161
}
134162

135163
// Insert to the front of the array so that remove tends to find it faster.

test/IRGen/access_markers.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -enforce-exclusivity=checked -assume-parsing-unqualified-ownership-sil %s -emit-ir | %FileCheck %s --check-prefix=CHECK
1+
// RUN: %target-swift-frontend -swift-version 4 -enforce-exclusivity=checked -assume-parsing-unqualified-ownership-sil %s -emit-ir | %FileCheck %s --check-prefix=CHECK
22

33
import Builtin
44
import Swift

test/IRGen/exclusivity.sil

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %target-swift-frontend %s -emit-ir -enforce-exclusivity=checked | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-%target-cpu %s
1+
// RUN: %target-swift-frontend %s -swift-version 4 -emit-ir -enforce-exclusivity=checked | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-SWIFT4 --check-prefix=CHECK-%target-cpu %s
2+
// RUN: %target-swift-frontend %s -swift-version 3 -emit-ir -enforce-exclusivity=checked | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-SWIFT3 --check-prefix=CHECK-%target-cpu %s
23

34
sil_stage canonical
45

@@ -24,8 +25,9 @@ bb0(%0 : $A):
2425
// CHECK: [[T0:%.*]] = bitcast [[BUFFER_T]]* [[SCRATCH0]] to i8*
2526
// CHECK: call void @llvm.lifetime.start(i64 -1, i8* [[T0]])
2627
// CHECK: [[T0:%.*]] = bitcast [[INT:%TSi]]* [[PROP]] to i8*
27-
// CHECK: call void @swift_beginAccess(i8* [[T0]], [[BUFFER_T]]* [[SCRATCH0]], [[SIZE_T:i32|i64]] 0, i8* null)
28-
%4 = begin_access [read] [dynamic] %3 : $*Int
28+
// CHECK-SWIFT3: call void @swift_beginAccess(i8* [[T0]], [[BUFFER_T]]* [[SCRATCH0]], [[SIZE_T:i32|i64]] 16, i8* null)
29+
// CHECK-SWIFT4: call void @swift_beginAccess(i8* [[T0]], [[BUFFER_T]]* [[SCRATCH0]], [[SIZE_T:i32|i64]] 0, i8* null)
30+
%4 = begin_access [read] [dynamic] %3 : $*Int
2931

3032
// CHECK: [[T0:%.*]] = getelementptr inbounds [[INT]], [[INT]]* %1, i32 0, i32 0
3133
// CHECK: load {{.*}}* [[T0]]
@@ -44,7 +46,8 @@ bb0(%0 : $A):
4446
// CHECK: [[T0:%.*]] = bitcast [[BUFFER_T]]* [[SCRATCH1]] to i8*
4547
// CHECK: call void @llvm.lifetime.start(i64 -1, i8* [[T0]])
4648
// CHECK: [[T0:%.*]] = bitcast [[INT:%TSi]]* [[PROP]] to i8*
47-
// CHECK: call void @swift_beginAccess(i8* [[T0]], [[BUFFER_T]]* [[SCRATCH1]], [[SIZE_T]] 1, i8* null)
49+
// CHECK-SWIFT3: call void @swift_beginAccess(i8* [[T0]], [[BUFFER_T]]* [[SCRATCH1]], [[SIZE_T:i32|i64]] 17, i8* null)
50+
// CHECK-SWIFT4: call void @swift_beginAccess(i8* [[T0]], [[BUFFER_T]]* [[SCRATCH1]], [[SIZE_T:i32|i64]] 1, i8* null)
4851
%12 = begin_access [modify] [dynamic] %11 : $*Int
4952

5053
// CHECK: call {{.*}} @changeInt([[INT]]*{{.*}} [[PROP]])

test/Interpreter/enforce_exclusive_access.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: rm -rf %t
22
// RUN: mkdir -p %t
3-
// RUN: %target-build-swift %s -o %t/a.out -enforce-exclusivity=checked -Onone
3+
// RUN: %target-build-swift -swift-version 4 %s -o %t/a.out -enforce-exclusivity=checked -Onone
44
//
55
// RUN: %target-run %t/a.out
66
// REQUIRES: executable_test

0 commit comments

Comments
 (0)