Skip to content

Commit 268de01

Browse files
committed
When determining the start of a declaration, ignore attributes that aren't at the start
Otherwise, we get bad attribute/modifier insertion locations for 'rethrows' functions
1 parent 7f50c1e commit 268de01

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

include/swift/AST/DeclAttr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ CONTEXTUAL_DECL_ATTR(weak, ReferenceOwnership,
429429
49)
430430
CONTEXTUAL_DECL_ATTR_ALIAS(unowned, ReferenceOwnership)
431431
SIMPLE_DECL_ATTR(rethrows, Rethrows,
432-
OnFunc | OnConstructor | RejectByParser | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
432+
OnFunc | OnConstructor | DeclModifier | RejectByParser | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
433433
57)
434434
CONTEXTUAL_SIMPLE_DECL_ATTR(indirect, Indirect,
435435
DeclModifier | OnEnum | OnEnumElement | ABIBreakingToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove,

lib/AST/Attr.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,12 +861,26 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
861861
DA->print(Printer, Options, D);
862862
}
863863

864+
static bool attributeIsNotAtStart(const DeclAttribute *attr) {
865+
switch (attr->getKind()) {
866+
case DeclAttrKind::Rethrows:
867+
case DeclAttrKind::Reasync:
868+
return true;
869+
870+
default:
871+
return false;
872+
}
873+
}
874+
864875
SourceLoc DeclAttributes::getStartLoc(bool forModifiers) const {
865876
if (isEmpty())
866877
return SourceLoc();
867878

868879
const DeclAttribute *lastAttr = nullptr;
869880
for (auto attr : *this) {
881+
if (attributeIsNotAtStart(attr))
882+
continue;
883+
870884
if (attr->getRangeWithAt().Start.isValid() &&
871885
(!forModifiers || attr->isDeclModifier()))
872886
lastAttr = attr;

test/Unsafe/safe.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
func unsafeFunction() { }
88

99
@unsafe
10-
struct UnsafeType { } // expected-note{{unsafe struct 'UnsafeType' declared here}}
10+
struct UnsafeType { } // expected-note 3{{unsafe struct 'UnsafeType' declared here}}
1111

1212
@safe(unchecked)
1313
func f() {
@@ -25,6 +25,14 @@ func h(_: UnsafeType) { // expected-warning{{reference to unsafe struct 'UnsafeT
2525
unsafeFunction()
2626
}
2727

28+
// expected-note@+1 {{make global function 'rethrowing' @unsafe to indicate that its use is not memory-safe}}{{1-1=@unsafe }}
29+
func rethrowing(body: (UnsafeType) throws -> Void) rethrows { } // expected-warning{{reference to unsafe struct 'UnsafeType' [Unsafe]}}
30+
31+
class HasStatics {
32+
// expected-note@+1{{make static method 'f' @unsafe to indicate that its use is not memory-safe}}{{3-3=@unsafe }}
33+
static func f(_: UnsafeType) { } // expected-warning{{reference to unsafe struct 'UnsafeType' [Unsafe]}}
34+
}
35+
2836
// Parsing issues
2937
@safe // expected-error{{expected '(' in 'safe' attribute}}
3038
func bad1() { }

0 commit comments

Comments
 (0)