diff options
| -rw-r--r-- | clang/include/clang/Basic/Attr.td | 3 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 | ||||
| -rw-r--r-- | clang/include/clang/Sema/AttributeList.h | 1 | ||||
| -rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 16 | ||||
| -rw-r--r-- | clang/test/Sema/attr-capabilities.c | 4 | ||||
| -rw-r--r-- | clang/test/SemaObjC/objcbridge-attribute-arc.m | 16 | ||||
| -rw-r--r-- | clang/test/SemaObjC/objcbridge-attribute.m | 22 |
8 files changed, 52 insertions, 19 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index a5450f91efe..40871021405 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -981,7 +981,8 @@ def NoThrow : InheritableAttr { def ObjCBridge : InheritableAttr { let Spellings = [GNU<"objc_bridge">]; - let Subjects = SubjectList<[Record], ErrorDiag>; + let Subjects = SubjectList<[Record, TypedefName], ErrorDiag, + "ExpectedStructOrUnionOrTypedef">; let Args = [IdentifierArgument<"BridgedType">]; let Documentation = [Undocumented]; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8090f7a61b8..bb448616aba 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2254,7 +2254,7 @@ def warn_attribute_wrong_decl_type : Warning< "struct or union|struct, union or class|types|" "Objective-C instance methods|init methods of interface or class extension declarations|" "variables, functions and classes|Objective-C protocols|" - "functions and global variables|structs or typedefs|" + "functions and global variables|structs, unions, and typedefs|structs and typedefs|" "interface or protocol declarations|kernel functions}1">, InGroup<IgnoredAttributes>; def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>; @@ -2734,6 +2734,10 @@ def warn_objc_implementation_missing_designated_init_override : Warning< // objc_bridge attribute diagnostics. def err_objc_attr_not_id : Error< "parameter of %0 attribute must be a single name of an Objective-C %select{class|protocol}1">; +def err_objc_attr_typedef_not_id : Error< + "parameter of %0 attribute must be 'id' when used on a typedef">; +def err_objc_attr_typedef_not_void_pointer : Error< + "'objc_bridge(id)' is only allowed on structs and typedefs of void pointers">; def err_objc_cf_bridged_not_interface : Error< "CF object of type %0 is bridged to %1, which is not an Objective-C class">; def err_objc_ns_bridged_invalid_cfobject : Error< diff --git a/clang/include/clang/Sema/AttributeList.h b/clang/include/clang/Sema/AttributeList.h index dc85f5d2084..ff16b8949ac 100644 --- a/clang/include/clang/Sema/AttributeList.h +++ b/clang/include/clang/Sema/AttributeList.h @@ -843,6 +843,7 @@ enum AttributeDeclKind { ExpectedFunctionVariableOrClass, ExpectedObjectiveCProtocol, ExpectedFunctionGlobalVarMethodOrProperty, + ExpectedStructOrUnionOrTypedef, ExpectedStructOrTypedef, ExpectedObjectiveCInterfaceOrProtocol, ExpectedKernelFunction diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index cd05d06633f..68c4f50df79 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -912,7 +912,8 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Case("objc_dictionary_literals", LangOpts.ObjC2) .Case("objc_boxed_expressions", LangOpts.ObjC2) .Case("arc_cf_code_audited", true) - .Case("objc_bridge_id", LangOpts.ObjC2) + .Case("objc_bridge_id", true) + .Case("objc_bridge_id_on_typedefs", true) // C11 features .Case("c_alignas", LangOpts.C11) .Case("c_alignof", LangOpts.C11) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 22df62bb731..80f141ef8d0 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3734,6 +3734,22 @@ static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D, S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0; return; } + + // Typedefs only allow objc_bridge(id) and have some additional checking. + if (auto TD = dyn_cast<TypedefNameDecl>(D)) { + if (!Parm->Ident->isStr("id")) { + S.Diag(Attr.getLoc(), diag::err_objc_attr_typedef_not_id) + << Attr.getName(); + return; + } + + // Only allow 'cv void *'. + QualType T = TD->getUnderlyingType(); + if (!T->isVoidPointerType()) { + S.Diag(Attr.getLoc(), diag::err_objc_attr_typedef_not_void_pointer); + return; + } + } D->addAttr(::new (S.Context) ObjCBridgeAttr(Attr.getRange(), S.Context, Parm->Ident, diff --git a/clang/test/Sema/attr-capabilities.c b/clang/test/Sema/attr-capabilities.c index cdbd2f3b2d2..5bfbdacf508 100644 --- a/clang/test/Sema/attr-capabilities.c +++ b/clang/test/Sema/attr-capabilities.c @@ -7,8 +7,8 @@ struct NotACapability {}; // Test an invalid capability name struct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}} -int Test1 __attribute__((capability("test1"))); // expected-error {{'capability' attribute only applies to structs or typedefs}} -int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs or typedefs}} +int Test1 __attribute__((capability("test1"))); // expected-error {{'capability' attribute only applies to structs and typedefs}} +int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs and typedefs}} int Test3 __attribute__((acquire_capability("test3"))); // expected-warning {{'acquire_capability' attribute only applies to functions}} int Test4 __attribute__((try_acquire_capability("test4"))); // expected-error {{'try_acquire_capability' attribute only applies to functions}} int Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}} diff --git a/clang/test/SemaObjC/objcbridge-attribute-arc.m b/clang/test/SemaObjC/objcbridge-attribute-arc.m index ab8cab8d191..e08bd3d023e 100644 --- a/clang/test/SemaObjC/objcbridge-attribute-arc.m +++ b/clang/test/SemaObjC/objcbridge-attribute-arc.m @@ -9,28 +9,30 @@ typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // e typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{'objc_bridge' attribute takes one argument}} -typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}} -typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef; -typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} + +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX; typedef XXX *CFUColor2Ref; @interface I { - __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; + __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}}; } @end diff --git a/clang/test/SemaObjC/objcbridge-attribute.m b/clang/test/SemaObjC/objcbridge-attribute.m index a268caef8a5..2969ebef36a 100644 --- a/clang/test/SemaObjC/objcbridge-attribute.m +++ b/clang/test/SemaObjC/objcbridge-attribute.m @@ -9,28 +9,36 @@ typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // e typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{'objc_bridge' attribute takes one argument}} -typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}} -typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef; // expected-note {{declared here}} -typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX; typedef XXX *CFUColor2Ref; +typedef const void *ConstVoidRef __attribute__((objc_bridge(id))); +typedef void *VoidRef __attribute__((objc_bridge(id))); +typedef struct Opaque *OpaqueRef __attribute__((objc_bridge(id))); // expected-error {{'objc_bridge(id)' is only allowed on structs and typedefs of void pointers}} + +#if !__has_feature(objc_bridge_id_on_typedefs) +#error objc_bridge(id) on typedefs feature not found! +#endif + @interface I { - __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; + __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}}; } @end |

