Skip to content

Commit 12102c4

Browse files
committed
[Sema] Warn if the @_originallyDefinedIn attribute is applied to a decl that is inaccessible outside the current module.
Resolves rdar://82441657
1 parent edf98aa commit 12102c4

File tree

4 files changed

+49
-8
lines changed

4 files changed

+49
-8
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,11 @@ ERROR(originally_definedin_need_available,none,
16071607
ERROR(originally_definedin_must_not_before_available_version,none,
16081608
"symbols are moved to the current module before they were available in the OSs", (StringRef))
16091609

1610+
WARNING(originally_defined_in_on_non_public,
1611+
none, "@%0 does not have any effect on "
1612+
"%select{private|fileprivate|internal|%error|%error}1 declarations",
1613+
(StringRef, AccessLevel))
1614+
16101615
// Alignment attribute
16111616
ERROR(alignment_not_power_of_two,none,
16121617
"alignment value must be a power of two", ())

lib/Sema/TypeCheckAttr.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3413,6 +3413,22 @@ void AttributeChecker::checkOriginalDefinedInAttrs(Decl *D,
34133413
// Attrs are in the reverse order of the source order. We need to visit them
34143414
// in source order to diagnose the later attribute.
34153415
for (auto *Attr: Attrs) {
3416+
static StringRef AttrName = "_originallyDefinedIn";
3417+
3418+
if (auto *VD = dyn_cast<ValueDecl>(D)) {
3419+
// This attribute does not make sense on private declarations since
3420+
// clients can't use them.
3421+
auto access =
3422+
VD->getFormalAccessScope(/*useDC=*/nullptr,
3423+
/*treatUsableFromInlineAsPublic=*/true);
3424+
if (!access.isPublic()) {
3425+
diagnoseAndRemoveAttr(Attr,
3426+
diag::originally_defined_in_on_non_public,
3427+
AttrName, VD->getFormalAccess());
3428+
continue;
3429+
}
3430+
}
3431+
34163432
if (!Attr->isActivePlatform(Ctx))
34173433
continue;
34183434
auto AtLoc = Attr->AtLoc;
@@ -3425,7 +3441,6 @@ void AttributeChecker::checkOriginalDefinedInAttrs(Decl *D,
34253441
platformString(Platform));
34263442
return;
34273443
}
3428-
static StringRef AttrName = "_originallyDefinedIn";
34293444
if (!D->getDeclContext()->isModuleScopeContext()) {
34303445
diagnose(AtLoc, diag::originally_definedin_topleve_decl, AttrName);
34313446
return;

test/ModuleInterface/originally-defined-attr.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,9 @@ public struct SimpleThingInAlphabeticalOrderForMacros1 {}
4242
@available(tvOS 0.7, OSX 1.1, iOS 2.1, watchOS 3.2, *)
4343
@_originallyDefinedIn(module: "other2", _myProject 1.0)
4444
public struct SimpleThingInAlphabeticalOrderForMacros2 {}
45+
46+
// CHECK: @_originallyDefinedIn(module: "another", macOS 13.13)
47+
@available(OSX 10.8, *)
48+
@_originallyDefinedIn(module: "another", OSX 13.13)
49+
@usableFromInline
50+
internal struct SimpleThingInAlphabeticalOrderForMacros3_UsableFromInline {}

test/Parse/original_defined_in_attr.swift

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,46 @@
22
// REQUIRES: OS=macosx
33

44
@_originallyDefinedIn(module: "foo", OSX 13.13) // expected-error {{need @available attribute for @_originallyDefinedIn}}
5-
func foo() {}
5+
public func foo() {}
66

77
@_originallyDefinedIn(modulename: "foo", OSX 13.13) // expected-error {{expected 'module: "original"' in the first argument to @_originallyDefinedIn}}
8-
func foo1() {}
8+
public func foo1() {}
99

1010
@_originallyDefinedIn(module: "foo", OSX 13.13.3) // expected-warning {{@_originallyDefinedIn only uses major and minor version number}} expected-error {{need @available attribute for @_originallyDefinedIn}}
11-
class ToplevelClass {}
11+
public class ToplevelClass {}
1212

1313
@_originallyDefinedIn(module: "foo") // expected-error {{expected at least one platform version in @_originallyDefinedIn}}
14-
class ToplevelClass1 {}
14+
public class ToplevelClass1 {}
1515

1616
@_originallyDefinedIn(OSX 13.13.3) // expected-error {{expected 'module: "original"' in the first argument to @_originallyDefinedIn}}
17-
class ToplevelClass2 {}
17+
public class ToplevelClass2 {}
1818

1919
@_originallyDefinedIn(module: "foo", // expected-error {{expected at least one platform version in @_originallyDefinedIn}}
20-
class ToplevelClass3 {}
20+
public class ToplevelClass3 {}
2121
2222
@available(OSX 13.10, *)
2323
@_originallyDefinedIn(module: "foo", * 13.13) // expected-warning {{* as platform name has no effect}} expected-error {{expected at least one platform version in @_originallyDefinedIn}}
2424
@_originallyDefinedIn(module: "foo", OSX 13.13, iOS 7.0)
2525
@_originallyDefinedIn(module: "foo", OSX 13.14, * 7.0) // expected-warning {{* as platform name has no effect}} expected-error {{duplicate version number for platform macOS}}
26-
class ToplevelClass4 {
26+
public class ToplevelClass4 {
2727
@_originallyDefinedIn(module: "foo", OSX 13.13) // expected-error {{'@_originallyDefinedIn' attribute cannot be applied to this declaration}}
2828
subscript(index: Int) -> Int {
2929
get { return 1 }
3030
set(newValue) {}
3131
}
3232
}
33+
34+
@available(OSX 13.10, *)
35+
@_originallyDefinedIn(module: "foo", OSX 13.13) // expected-warning {{@_originallyDefinedIn does not have any effect on internal declarations}}
36+
@_originallyDefinedIn(module: "foo", iOS 7.0) // expected-warning {{@_originallyDefinedIn does not have any effect on internal declarations}}
37+
internal class ToplevelClass5 {}
38+
39+
@available(OSX 13.10, *)
40+
@_originallyDefinedIn(module: "foo", OSX 13.13) // expected-warning {{@_originallyDefinedIn does not have any effect on private declarations}}
41+
@_originallyDefinedIn(module: "foo", iOS 7.0) // expected-warning {{@_originallyDefinedIn does not have any effect on private declarations}}
42+
private class ToplevelClass6 {}
43+
44+
@available(OSX 13.10, *)
45+
@_originallyDefinedIn(module: "foo", OSX 13.13) // expected-warning {{@_originallyDefinedIn does not have any effect on fileprivate declarations}}
46+
@_originallyDefinedIn(module: "foo", iOS 7.0) // expected-warning {{@_originallyDefinedIn does not have any effect on fileprivate declarations}}
47+
fileprivate class ToplevelClass7 {}

0 commit comments

Comments
 (0)