Skip to content

Commit 88b3c57

Browse files
Merge pull request #69769 from nate-chandler/rdar116877403
[Diagnostics] Allow multiple non-custom _effects.
2 parents cabb5e1 + 648cede commit 88b3c57

File tree

2 files changed

+79
-7
lines changed

2 files changed

+79
-7
lines changed

lib/SIL/IR/SILFunctionBuilder.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,15 @@ void SILFunctionBuilder::addFunctionAttributes(
110110
auto *effectsAttr = cast<EffectsAttr>(attr);
111111
if (effectsAttr->getKind() == EffectsKind::Custom) {
112112
customEffects.push_back(effectsAttr);
113+
continue;
114+
}
115+
if (F->getEffectsKind() != EffectsKind::Unspecified) {
116+
// If multiple known effects are specified, the most restrictive one
117+
// is used.
118+
F->setEffectsKind(
119+
std::min(effectsAttr->getKind(), F->getEffectsKind()));
113120
} else {
114-
if (F->getEffectsKind() != EffectsKind::Unspecified &&
115-
F->getEffectsKind() != effectsAttr->getKind()) {
116-
mod.getASTContext().Diags.diagnose(effectsAttr->getLocation(),
117-
diag::warning_in_effects_attribute, "mismatching function effects");
118-
} else {
119-
F->setEffectsKind(effectsAttr->getKind());
120-
}
121+
F->setEffectsKind(effectsAttr->getKind());
121122
}
122123
}
123124
}

test/SIL/diagnose_effects.swift

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// RUN: %target-swift-emit-silgen %s -o /dev/null -verify
2+
class C {}
3+
struct S {
4+
5+
var c: C
6+
7+
////////////////////////////////////////////////////////////////////////////////
8+
// Implicitly consuming argument. //
9+
////////////////////////////////////////////////////////////////////////////////
10+
@_effects(readnone) @_effects(releasenone) // ok
11+
init(readnone_releasenone c: C) { self.c = c }
12+
13+
@_effects(releasenone) @_effects(readnone) // ok
14+
init(releasenone_readnone c: C) { self.c = c }
15+
16+
@_effects(readonly) @_effects(releasenone) // ok
17+
init(readonly_releasenone c: C) { self.c = c }
18+
19+
@_effects(releasenone) @_effects(readonly) // ok
20+
init(releasenone_readonly c: C) { self.c = c }
21+
22+
@_effects(releasenone) // ok
23+
init(releasenone c: C) { self.c = c }
24+
25+
////////////////////////////////////////////////////////////////////////////////
26+
// Explicitly consuming argument. //
27+
////////////////////////////////////////////////////////////////////////////////
28+
@_effects(readnone) @_effects(releasenone) // ok
29+
mutating func readnone_releasenoneConsumeParam(_ c: consuming C) {
30+
self.c = c
31+
}
32+
33+
@_effects(releasenone) @_effects(readnone) // ok
34+
mutating func releasenone_readnoneConsumeParam(_ c: consuming C) {
35+
self.c = c
36+
}
37+
38+
@_effects(readonly) @_effects(releasenone) // ok
39+
mutating func reasonly_releasenoneConsumeParam(_ c: consuming C) {
40+
self.c = c
41+
}
42+
43+
@_effects(releasenone) @_effects(readonly) // ok
44+
mutating func releasenone_reasonlyConsumeParam(_ c: consuming C) {
45+
self.c = c
46+
}
47+
48+
@_effects(releasenone) // ok
49+
mutating func releasenoneConsumeParam(_ c: consuming C) {
50+
self.c = c
51+
}
52+
53+
////////////////////////////////////////////////////////////////////////////////
54+
// Explicitly consuming self. //
55+
////////////////////////////////////////////////////////////////////////////////
56+
@_effects(readnone) @_effects(releasenone) // ok
57+
__consuming func readnone_releasenoneConsumeSelf() {}
58+
59+
@_effects(releasenone) @_effects(readnone) // ok
60+
__consuming func readnone_readnoneConsumeSelf() {}
61+
62+
@_effects(readonly) @_effects(releasenone) // ok
63+
__consuming func readonly_releasenoneConsumeSelf() {}
64+
65+
@_effects(releasenone) @_effects(readonly) // ok
66+
__consuming func releasenone_readonlyConsumeSelf() {}
67+
68+
@_effects(releasenone) // ok
69+
__consuming func releasenoneConsumeSelf() {}
70+
71+
}

0 commit comments

Comments
 (0)