Skip to content

Commit 50a98d3

Browse files
authored
Merge pull request #69422 from beccadax/implementation-blocked
Forbid @objcImpl on root and generic classes
2 parents c643f6b + 6b795a4 commit 50a98d3

File tree

5 files changed

+38
-1
lines changed

5 files changed

+38
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,13 @@ ERROR(attr_objc_implementation_must_be_imported,none,
17181718
"defined by a Swift 'class' declaration, not an imported Objective-C "
17191719
"'@interface' declaration",
17201720
(ValueDecl *))
1721+
ERROR(attr_objc_implementation_must_have_super,none,
1722+
"'@_objcImplementation' cannot be used to implement root %kind0; declare "
1723+
"its superclass in the header",
1724+
(ValueDecl *))
1725+
ERROR(objc_implementation_cannot_have_generics,none,
1726+
"'@_objcImplementation' cannot be used to implement %kind0",
1727+
(ValueDecl *))
17211728
ERROR(attr_objc_implementation_category_not_found,none,
17221729
"could not find category %0 on Objective-C class %1; make sure your "
17231730
"umbrella or bridging header imports the header that declares it",

lib/AST/Decl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1825,7 +1825,8 @@ llvm::Optional<Identifier>
18251825
ExtensionDecl::getCategoryNameForObjCImplementation() const {
18261826
assert(isObjCImplementation());
18271827

1828-
auto attr = getAttrs().getAttribute<ObjCImplementationAttr>();
1828+
auto attr = getAttrs()
1829+
.getAttribute<ObjCImplementationAttr>(/*AllowInvalid=*/true);
18291830
if (attr->isCategoryNameInvalid())
18301831
return llvm::None;
18311832

lib/Sema/TypeCheckAttr.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,19 @@ visitObjCImplementationAttr(ObjCImplementationAttr *attr) {
15031503
return;
15041504
}
15051505

1506+
if (!CD->hasSuperclass()) {
1507+
diagnoseAndRemoveAttr(attr, diag::attr_objc_implementation_must_have_super,
1508+
CD);
1509+
CD->diagnose(diag::decl_declared_here, CD);
1510+
return;
1511+
}
1512+
1513+
if (CD->isTypeErasedGenericClass()) {
1514+
diagnoseAndRemoveAttr(attr, diag::objc_implementation_cannot_have_generics,
1515+
CD);
1516+
CD->diagnose(diag::decl_declared_here, CD);
1517+
}
1518+
15061519
if (!attr->isCategoryNameInvalid() && !ED->getImplementedObjCDecl()) {
15071520
diagnose(attr->getLocation(),
15081521
diag::attr_objc_implementation_category_not_found,

test/decl/ext/Inputs/objc_implementation.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,14 @@
168168

169169
@end
170170

171+
@interface ObjCImplRootClass
172+
173+
@end
174+
175+
@interface ObjCImplGenericClass<T> : NSObject
176+
177+
@end
178+
171179

172180

173181
struct ObjCStruct {

test/decl/ext/objc_implementation.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,14 @@ protocol EmptySwiftProto {}
456456
@_objcImplementation(WTF) extension SwiftClass {} // expected
457457
// expected-error@-1 {{'@_objcImplementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{1-27=}}
458458

459+
@_objcImplementation extension ObjCImplRootClass {
460+
// expected-error@-1 {{'@_objcImplementation' cannot be used to implement root class 'ObjCImplRootClass'; declare its superclass in the header}}
461+
}
462+
463+
@_objcImplementation extension ObjCImplGenericClass {
464+
// expected-error@-1 {{'@_objcImplementation' cannot be used to implement generic class 'ObjCImplGenericClass'}}
465+
}
466+
459467
func usesAreNotAmbiguous(obj: ObjCClass) {
460468
obj.method(fromHeader1: 1)
461469
obj.method(fromHeader2: 2)

0 commit comments

Comments
 (0)