Skip to content

Commit fc22ba6

Browse files
committed
[TypeChecker] Don't verify override access control if it has been disabled by a flag
1 parent af34984 commit fc22ba6

File tree

4 files changed

+109
-49
lines changed

4 files changed

+109
-49
lines changed

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 58 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -759,55 +759,15 @@ SmallVector<OverrideMatch, 2> OverrideMatcher::match(
759759
return matches;
760760
}
761761

762-
bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
763-
OverrideCheckingAttempt attempt) {
764-
auto &diags = ctx.Diags;
765-
auto baseTy = getMemberTypeForComparison(ctx, baseDecl, decl);
766-
bool emittedMatchError = false;
767-
768-
// If the name of our match differs from the name we were looking for,
769-
// complain.
770-
if (decl->getFullName() != baseDecl->getFullName()) {
771-
auto diag = diags.diagnose(decl, diag::override_argument_name_mismatch,
772-
isa<ConstructorDecl>(decl),
773-
decl->getFullName(),
774-
baseDecl->getFullName());
775-
fixDeclarationName(diag, decl, baseDecl->getFullName());
776-
emittedMatchError = true;
777-
}
762+
static void checkOverrideAccessControl(ValueDecl *baseDecl, ValueDecl *decl,
763+
ASTContext &ctx) {
764+
if (!ctx.LangOpts.EnableAccessControl)
765+
return;
778766

779-
// If we have an explicit ownership modifier and our parent doesn't,
780-
// complain.
781-
auto parentAttr =
782-
baseDecl->getAttrs().getAttribute<ReferenceOwnershipAttr>();
783-
if (auto ownershipAttr =
784-
decl->getAttrs().getAttribute<ReferenceOwnershipAttr>()) {
785-
ReferenceOwnership parentOwnership;
786-
if (parentAttr)
787-
parentOwnership = parentAttr->get();
788-
else
789-
parentOwnership = ReferenceOwnership::Strong;
790-
if (parentOwnership != ownershipAttr->get()) {
791-
diags.diagnose(decl, diag::override_ownership_mismatch,
792-
parentOwnership, ownershipAttr->get());
793-
diags.diagnose(baseDecl, diag::overridden_here);
794-
}
795-
}
767+
auto &diags = ctx.Diags;
796768

797-
// If a super method returns Self, and the subclass overrides it to
798-
// instead return the subclass type, complain.
799-
// This case gets this far because the type matching above specifically
800-
// strips out dynamic self via replaceCovariantResultType(), and that
801-
// is helpful in several cases - just not this one.
802769
auto dc = decl->getDeclContext();
803770
auto classDecl = dc->getSelfClassDecl();
804-
if (decl->getASTContext().isSwiftVersionAtLeast(5) &&
805-
baseDecl->getInterfaceType()->hasDynamicSelfType() &&
806-
!decl->getInterfaceType()->hasDynamicSelfType() &&
807-
!classDecl->isFinal()) {
808-
diags.diagnose(decl, diag::override_dynamic_self_mismatch);
809-
diags.diagnose(baseDecl, diag::overridden_here);
810-
}
811771

812772
bool isAccessor = isa<AccessorDecl>(decl);
813773

@@ -891,6 +851,59 @@ bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
891851
diags.diagnose(baseDecl, diag::overridden_here);
892852
}
893853
}
854+
}
855+
856+
bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
857+
OverrideCheckingAttempt attempt) {
858+
auto &diags = ctx.Diags;
859+
auto baseTy = getMemberTypeForComparison(ctx, baseDecl, decl);
860+
bool emittedMatchError = false;
861+
862+
// If the name of our match differs from the name we were looking for,
863+
// complain.
864+
if (decl->getFullName() != baseDecl->getFullName()) {
865+
auto diag = diags.diagnose(decl, diag::override_argument_name_mismatch,
866+
isa<ConstructorDecl>(decl),
867+
decl->getFullName(),
868+
baseDecl->getFullName());
869+
fixDeclarationName(diag, decl, baseDecl->getFullName());
870+
emittedMatchError = true;
871+
}
872+
873+
// If we have an explicit ownership modifier and our parent doesn't,
874+
// complain.
875+
auto parentAttr =
876+
baseDecl->getAttrs().getAttribute<ReferenceOwnershipAttr>();
877+
if (auto ownershipAttr =
878+
decl->getAttrs().getAttribute<ReferenceOwnershipAttr>()) {
879+
ReferenceOwnership parentOwnership;
880+
if (parentAttr)
881+
parentOwnership = parentAttr->get();
882+
else
883+
parentOwnership = ReferenceOwnership::Strong;
884+
if (parentOwnership != ownershipAttr->get()) {
885+
diags.diagnose(decl, diag::override_ownership_mismatch,
886+
parentOwnership, ownershipAttr->get());
887+
diags.diagnose(baseDecl, diag::overridden_here);
888+
}
889+
}
890+
891+
// If a super method returns Self, and the subclass overrides it to
892+
// instead return the subclass type, complain.
893+
// This case gets this far because the type matching above specifically
894+
// strips out dynamic self via replaceCovariantResultType(), and that
895+
// is helpful in several cases - just not this one.
896+
auto dc = decl->getDeclContext();
897+
auto classDecl = dc->getSelfClassDecl();
898+
if (decl->getASTContext().isSwiftVersionAtLeast(5) &&
899+
baseDecl->getInterfaceType()->hasDynamicSelfType() &&
900+
!decl->getInterfaceType()->hasDynamicSelfType() &&
901+
!classDecl->isFinal()) {
902+
diags.diagnose(decl, diag::override_dynamic_self_mismatch);
903+
diags.diagnose(baseDecl, diag::overridden_here);
904+
}
905+
906+
checkOverrideAccessControl(baseDecl, decl, ctx);
894907

895908
bool mayHaveMismatchedOptionals =
896909
(attempt == OverrideCheckingAttempt::MismatchedOptional ||

test/Interpreter/repl.swift

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,32 @@ if true && true { if true && true { print(true && true) } }
223223
// CHECK: = "ok"
224224

225225
// Make sure that class inheritance works
226-
class A {}
226+
class A {
227+
var foo: String { return "" }
228+
func bar() -> String { return "" }
229+
subscript(_ x: Int) -> String { return "" }
230+
}
231+
227232
class B : A {
233+
override var foo: String {
234+
return "property ok"
235+
}
236+
228237
override init() {}
229-
func foo() -> String { return "ok" }
238+
239+
override func bar() -> String {
240+
return "instance ok"
241+
}
242+
243+
override subscript(_ x: Int) -> String {
244+
return "subscript ok"
245+
}
230246
}
231247

232-
let _ = B().foo()
233-
// CHECK: = "ok"
248+
let b = B()
249+
let _ = b.foo
250+
// CHECK: = "property ok"
251+
let _ = b.bar()
252+
// CHECK: = "instance ok"
253+
let _ = b[42]
254+
// CHECK: = "subscript ok"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public class A {
2+
public init() {}
3+
public var foo: String { return "" }
4+
public func bar() {}
5+
public subscript(_ x: Int) -> String { return "" }
6+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -o %t/disabled_access_control_base.swiftmodule %S/Inputs/disabled_access_control_base.swift
3+
// RUN: %target-swift-frontend -disable-access-control -I %t -typecheck %s
4+
5+
import disabled_access_control_base
6+
7+
class B : A {
8+
public override var foo: String {
9+
return "ok"
10+
}
11+
12+
override init() { }
13+
14+
override func bar() {
15+
}
16+
17+
override subscript(_ x: Int) -> String {
18+
return "ok"
19+
}
20+
}

0 commit comments

Comments
 (0)