erik.pilkington updated this revision to Diff 186712.
erik.pilkington marked an inline comment as done.
erik.pilkington added a comment.
Remove an `auto`.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D58152/new/
https://reviews.llvm.org/D58152
Files:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Misc/pragma-attribute-supported-attributes-list.test
clang/test/SemaObjC/attr-designated-init.m
Index: clang/test/SemaObjC/attr-designated-init.m
===================================================================
--- clang/test/SemaObjC/attr-designated-init.m
+++ clang/test/SemaObjC/attr-designated-init.m
@@ -3,7 +3,7 @@
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
#define NS_UNAVAILABLE __attribute__((unavailable))
-void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
+void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{'objc_designated_initializer' attribute only applies to Objective-C methods}}
@protocol P1
-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
@@ -428,3 +428,12 @@
@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
- (instancetype)init NS_DESIGNATED_INITIALIZER; // expected-error{{only applies to init methods of interface or class extension declarations}}
@end
+
+@interface TwoAttrs
+- (instancetype)foo
+ __attribute__((objc_designated_initializer))
+ __attribute__((objc_method_family(init)));
+- (instancetype)bar
+ __attribute__((objc_method_family(init)))
+ __attribute__((objc_designated_initializer));
+@end
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===================================================================
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -97,6 +97,7 @@
// CHECK-NEXT: ObjCBridge (SubjectMatchRule_record, SubjectMatchRule_type_alias)
// CHECK-NEXT: ObjCBridgeMutable (SubjectMatchRule_record)
// CHECK-NEXT: ObjCBridgeRelated (SubjectMatchRule_record)
+// CHECK-NEXT: ObjCDesignatedInitializer (SubjectMatchRule_objc_method)
// CHECK-NEXT: ObjCException (SubjectMatchRule_objc_interface)
// CHECK-NEXT: ObjCExplicitProtocolImpl (SubjectMatchRule_objc_protocol)
// CHECK-NEXT: ObjCExternallyRetained (SubjectMatchRule_variable_not_is_parameter, SubjectMatchRule_function, SubjectMatchRule_block, SubjectMatchRule_objc_method)
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -5249,11 +5249,22 @@
static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
const ParsedAttr &AL) {
+ DeclContext *Ctx = D->getDeclContext();
+
+ // This attribute can only be applied to methods in interfaces or class
+ // extensions.
+ if (!isa<ObjCInterfaceDecl>(Ctx) &&
+ !(isa<ObjCCategoryDecl>(Ctx) &&
+ cast<ObjCCategoryDecl>(Ctx)->IsClassExtension())) {
+ S.Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
+ return;
+ }
+
ObjCInterfaceDecl *IFace;
- if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
+ if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Ctx))
IFace = CatDecl->getClassInterface();
else
- IFace = cast<ObjCInterfaceDecl>(D->getDeclContext());
+ IFace = cast<ObjCInterfaceDecl>(Ctx);
if (!IFace)
return;
@@ -7243,6 +7254,17 @@
}
}
}
+
+ // Do this check after processing D's attributes because the attribute
+ // objc_method_family can change whether the given method is in the init
+ // family, and it can be applied after objc_designated_initializer. This is a
+ // bit of a hack, but we need it to be compatible with versions of clang that
+ // processed the attribute list in the wrong order.
+ if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
+ cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {
+ Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
+ D->dropAttr<ObjCDesignatedInitializerAttr>();
+ }
}
// Helper for delayed processing TransparentUnion attribute.
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3481,6 +3481,9 @@
def warn_objc_implementation_missing_designated_init_override : Warning<
"method override for the designated initializer of the superclass %objcinstance0 not found">,
InGroup<ObjCDesignatedInit>;
+def err_designated_init_attr_non_init : Error<
+ "'objc_designated_initializer' attribute only applies to init methods "
+ "of interface or class extension declarations">;
// objc_bridge attribute diagnostics.
def err_objc_attr_not_id : Error<
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -102,13 +102,6 @@
[{S->isInstanceMethod()}],
"Objective-C instance methods">;
-def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
- [{S->getMethodFamily() == OMF_init &&
- (isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
- (isa<ObjCCategoryDecl>(S->getDeclContext()) &&
- cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}],
- "init methods of interface or class extension declarations">;
-
def Struct : SubsetSubject<Record,
[{!S->isUnion()}], "structs">;
@@ -1786,7 +1779,7 @@
def ObjCDesignatedInitializer : Attr {
let Spellings = [Clang<"objc_designated_initializer">];
- let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>;
+ let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
let Documentation = [Undocumented];
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits