mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[TypeChecker] Don't verify override access control if it has been disabled by a flag
This commit is contained in:
@@ -759,55 +759,15 @@ SmallVector<OverrideMatch, 2> OverrideMatcher::match(
|
||||
return matches;
|
||||
}
|
||||
|
||||
bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
|
||||
OverrideCheckingAttempt attempt) {
|
||||
static void checkOverrideAccessControl(ValueDecl *baseDecl, ValueDecl *decl,
|
||||
ASTContext &ctx) {
|
||||
if (!ctx.LangOpts.EnableAccessControl)
|
||||
return;
|
||||
|
||||
auto &diags = ctx.Diags;
|
||||
auto baseTy = getMemberTypeForComparison(ctx, baseDecl, decl);
|
||||
bool emittedMatchError = false;
|
||||
|
||||
// If the name of our match differs from the name we were looking for,
|
||||
// complain.
|
||||
if (decl->getFullName() != baseDecl->getFullName()) {
|
||||
auto diag = diags.diagnose(decl, diag::override_argument_name_mismatch,
|
||||
isa<ConstructorDecl>(decl),
|
||||
decl->getFullName(),
|
||||
baseDecl->getFullName());
|
||||
fixDeclarationName(diag, decl, baseDecl->getFullName());
|
||||
emittedMatchError = true;
|
||||
}
|
||||
|
||||
// If we have an explicit ownership modifier and our parent doesn't,
|
||||
// complain.
|
||||
auto parentAttr =
|
||||
baseDecl->getAttrs().getAttribute<ReferenceOwnershipAttr>();
|
||||
if (auto ownershipAttr =
|
||||
decl->getAttrs().getAttribute<ReferenceOwnershipAttr>()) {
|
||||
ReferenceOwnership parentOwnership;
|
||||
if (parentAttr)
|
||||
parentOwnership = parentAttr->get();
|
||||
else
|
||||
parentOwnership = ReferenceOwnership::Strong;
|
||||
if (parentOwnership != ownershipAttr->get()) {
|
||||
diags.diagnose(decl, diag::override_ownership_mismatch,
|
||||
parentOwnership, ownershipAttr->get());
|
||||
diags.diagnose(baseDecl, diag::overridden_here);
|
||||
}
|
||||
}
|
||||
|
||||
// If a super method returns Self, and the subclass overrides it to
|
||||
// instead return the subclass type, complain.
|
||||
// This case gets this far because the type matching above specifically
|
||||
// strips out dynamic self via replaceCovariantResultType(), and that
|
||||
// is helpful in several cases - just not this one.
|
||||
auto dc = decl->getDeclContext();
|
||||
auto classDecl = dc->getSelfClassDecl();
|
||||
if (decl->getASTContext().isSwiftVersionAtLeast(5) &&
|
||||
baseDecl->getInterfaceType()->hasDynamicSelfType() &&
|
||||
!decl->getInterfaceType()->hasDynamicSelfType() &&
|
||||
!classDecl->isFinal()) {
|
||||
diags.diagnose(decl, diag::override_dynamic_self_mismatch);
|
||||
diags.diagnose(baseDecl, diag::overridden_here);
|
||||
}
|
||||
|
||||
bool isAccessor = isa<AccessorDecl>(decl);
|
||||
|
||||
@@ -891,6 +851,59 @@ bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
|
||||
diags.diagnose(baseDecl, diag::overridden_here);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OverrideMatcher::checkOverride(ValueDecl *baseDecl,
|
||||
OverrideCheckingAttempt attempt) {
|
||||
auto &diags = ctx.Diags;
|
||||
auto baseTy = getMemberTypeForComparison(ctx, baseDecl, decl);
|
||||
bool emittedMatchError = false;
|
||||
|
||||
// If the name of our match differs from the name we were looking for,
|
||||
// complain.
|
||||
if (decl->getFullName() != baseDecl->getFullName()) {
|
||||
auto diag = diags.diagnose(decl, diag::override_argument_name_mismatch,
|
||||
isa<ConstructorDecl>(decl),
|
||||
decl->getFullName(),
|
||||
baseDecl->getFullName());
|
||||
fixDeclarationName(diag, decl, baseDecl->getFullName());
|
||||
emittedMatchError = true;
|
||||
}
|
||||
|
||||
// If we have an explicit ownership modifier and our parent doesn't,
|
||||
// complain.
|
||||
auto parentAttr =
|
||||
baseDecl->getAttrs().getAttribute<ReferenceOwnershipAttr>();
|
||||
if (auto ownershipAttr =
|
||||
decl->getAttrs().getAttribute<ReferenceOwnershipAttr>()) {
|
||||
ReferenceOwnership parentOwnership;
|
||||
if (parentAttr)
|
||||
parentOwnership = parentAttr->get();
|
||||
else
|
||||
parentOwnership = ReferenceOwnership::Strong;
|
||||
if (parentOwnership != ownershipAttr->get()) {
|
||||
diags.diagnose(decl, diag::override_ownership_mismatch,
|
||||
parentOwnership, ownershipAttr->get());
|
||||
diags.diagnose(baseDecl, diag::overridden_here);
|
||||
}
|
||||
}
|
||||
|
||||
// If a super method returns Self, and the subclass overrides it to
|
||||
// instead return the subclass type, complain.
|
||||
// This case gets this far because the type matching above specifically
|
||||
// strips out dynamic self via replaceCovariantResultType(), and that
|
||||
// is helpful in several cases - just not this one.
|
||||
auto dc = decl->getDeclContext();
|
||||
auto classDecl = dc->getSelfClassDecl();
|
||||
if (decl->getASTContext().isSwiftVersionAtLeast(5) &&
|
||||
baseDecl->getInterfaceType()->hasDynamicSelfType() &&
|
||||
!decl->getInterfaceType()->hasDynamicSelfType() &&
|
||||
!classDecl->isFinal()) {
|
||||
diags.diagnose(decl, diag::override_dynamic_self_mismatch);
|
||||
diags.diagnose(baseDecl, diag::overridden_here);
|
||||
}
|
||||
|
||||
checkOverrideAccessControl(baseDecl, decl, ctx);
|
||||
|
||||
bool mayHaveMismatchedOptionals =
|
||||
(attempt == OverrideCheckingAttempt::MismatchedOptional ||
|
||||
|
||||
@@ -223,11 +223,32 @@ if true && true { if true && true { print(true && true) } }
|
||||
// CHECK: = "ok"
|
||||
|
||||
// Make sure that class inheritance works
|
||||
class A {}
|
||||
class B : A {
|
||||
override init() {}
|
||||
func foo() -> String { return "ok" }
|
||||
class A {
|
||||
var foo: String { return "" }
|
||||
func bar() -> String { return "" }
|
||||
subscript(_ x: Int) -> String { return "" }
|
||||
}
|
||||
|
||||
let _ = B().foo()
|
||||
// CHECK: = "ok"
|
||||
class B : A {
|
||||
override var foo: String {
|
||||
return "property ok"
|
||||
}
|
||||
|
||||
override init() {}
|
||||
|
||||
override func bar() -> String {
|
||||
return "instance ok"
|
||||
}
|
||||
|
||||
override subscript(_ x: Int) -> String {
|
||||
return "subscript ok"
|
||||
}
|
||||
}
|
||||
|
||||
let b = B()
|
||||
let _ = b.foo
|
||||
// CHECK: = "property ok"
|
||||
let _ = b.bar()
|
||||
// CHECK: = "instance ok"
|
||||
let _ = b[42]
|
||||
// CHECK: = "subscript ok"
|
||||
|
||||
6
test/attr/Inputs/disabled_access_control_base.swift
Normal file
6
test/attr/Inputs/disabled_access_control_base.swift
Normal file
@@ -0,0 +1,6 @@
|
||||
public class A {
|
||||
public init() {}
|
||||
public var foo: String { return "" }
|
||||
public func bar() {}
|
||||
public subscript(_ x: Int) -> String { return "" }
|
||||
}
|
||||
20
test/attr/override_with_disabled_access_control.swift
Normal file
20
test/attr/override_with_disabled_access_control.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend -emit-module -o %t/disabled_access_control_base.swiftmodule %S/Inputs/disabled_access_control_base.swift
|
||||
// RUN: %target-swift-frontend -disable-access-control -I %t -typecheck %s
|
||||
|
||||
import disabled_access_control_base
|
||||
|
||||
class B : A {
|
||||
public override var foo: String {
|
||||
return "ok"
|
||||
}
|
||||
|
||||
override init() { }
|
||||
|
||||
override func bar() {
|
||||
}
|
||||
|
||||
override subscript(_ x: Int) -> String {
|
||||
return "ok"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user