Skip to content

Commit 5412419

Browse files
committed
Look past autoclosures when determining where to insert "unsafe" in a Fix-It
Otherwise, we'll end up inserting the "unsafe" on the right-hand side of an &&
1 parent 1cbeee6 commit 5412419

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3167,12 +3167,13 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
31673167
/// anchor expression, so we can emit diagnostics at the end.
31683168
llvm::MapVector<Expr *, std::vector<UnsafeUse>> uncoveredUnsafeUses;
31693169

3170-
static bool isEffectAnchor(Expr *e) {
3170+
static bool isEffectAnchor(Expr *e, bool stopAtAutoClosure) {
31713171
if (e->getLoc().isInvalid())
31723172
return false;
31733173

3174-
return isa<AbstractClosureExpr>(e) || isa<DiscardAssignmentExpr>(e) ||
3175-
isa<AssignExpr>(e);
3174+
return isa<ClosureExpr>(e) || isa<DiscardAssignmentExpr>(e) ||
3175+
isa<AssignExpr>(e) ||
3176+
(stopAtAutoClosure && isa<AutoClosureExpr>(e));
31763177
}
31773178

31783179
static bool isAnchorTooEarly(Expr *e) {
@@ -3181,11 +3182,12 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
31813182

31823183
/// Find the top location where we should put the await
31833184
static Expr *walkToAnchor(Expr *e, llvm::DenseMap<Expr *, Expr *> &parentMap,
3184-
bool isInterpolatedString) {
3185+
bool isInterpolatedString,
3186+
bool stopAtAutoClosure) {
31853187
llvm::SmallPtrSet<Expr *, 4> visited;
31863188
Expr *parent = e;
31873189
Expr *lastParent = e;
3188-
while (parent && !isEffectAnchor(parent)) {
3190+
while (parent && !isEffectAnchor(parent, stopAtAutoClosure)) {
31893191
lastParent = parent;
31903192
parent = parentMap[parent];
31913193

@@ -3890,7 +3892,8 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
38903892
Flags.has(ContextFlags::InAsyncLet))) {
38913893
Expr *expr = E.dyn_cast<Expr*>();
38923894
Expr *anchor = walkToAnchor(expr, parentMap,
3893-
CurContext.isWithinInterpolatedString());
3895+
CurContext.isWithinInterpolatedString(),
3896+
/*stopAtAutoClosure=*/true);
38943897
if (Flags.has(ContextFlags::StmtExprCoversAwait))
38953898
classification.setDowngradeToWarning(true);
38963899
if (uncoveredAsync.find(anchor) == uncoveredAsync.end())
@@ -3915,7 +3918,8 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
39153918
if (!Flags.has(ContextFlags::IsUnsafeCovered)) {
39163919
Expr *expr = E.dyn_cast<Expr*>();
39173920
Expr *anchor = walkToAnchor(expr, parentMap,
3918-
CurContext.isWithinInterpolatedString());
3921+
CurContext.isWithinInterpolatedString(),
3922+
/*stopAtAutoClosure=*/false);
39193923

39203924
// Figure out a location to use if the unsafe use didn't have one.
39213925
SourceLoc replacementLoc;

test/Unsafe/unsafe.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ func testConstruction() {
136136
// expected-note@-1{{reference to unsafe initializer 'init(count:)'}}
137137
}
138138

139+
func testRHS(b: Bool, x: Int) {
140+
@unsafe let limit = 17
141+
if b && x > limit { // expected-warning{{expression uses unsafe constructs but is not marked with 'unsafe' [Unsafe]}}{{6-6=unsafe }}
142+
// expected-note@-1{{reference to unsafe let 'limit'}}
143+
}
144+
}
145+
139146
// -----------------------------------------------------------------------
140147
// Declaration references
141148
// -----------------------------------------------------------------------

0 commit comments

Comments
 (0)