summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/Attr.td3
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td6
-rw-r--r--clang/include/clang/Sema/AttributeList.h1
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp3
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp16
-rw-r--r--clang/test/Sema/attr-capabilities.c4
-rw-r--r--clang/test/SemaObjC/objcbridge-attribute-arc.m16
-rw-r--r--clang/test/SemaObjC/objcbridge-attribute.m22
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
OpenPOWER on IntegriCloud