From: Ted Kremenek Date: Mon, 24 Jun 2013 21:35:39 +0000 (+0000) Subject: Tweak -Wdeprecated-objc-pointer-introspection to have a subgroup for results of using... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ea943145787bd286256b72c3e658db27674cfc44;p=clang Tweak -Wdeprecated-objc-pointer-introspection to have a subgroup for results of using -performSelectorXXX. -performSelector: and friends return a value that is boxed as an Objective-C pointer. Sometimes it is an Objective-C pointer, sometimes it isn't. Some clients may wish to silence this warning based on calling this method. Fixes git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184789 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 31b0b5623e..c1734506bc 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -208,6 +208,8 @@ def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">; def ObjCRetainBlockProperty : DiagGroup<"objc-noncopy-retain-block-property">; def ObjCReadonlyPropertyHasSetter : DiagGroup<"objc-readonly-with-setter-property">; def ObjCRootClass : DiagGroup<"objc-root-class">; +def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-introspection-performSelector">; +def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>; def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">; def Packed : DiagGroup<"packed">; def Padded : DiagGroup<"padded">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5d7d2372bd..bb532eb04c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -661,7 +661,9 @@ def warn_objc_isa_assign : Warning< def warn_objc_pointer_masking : Warning< "bitmasking for introspection of Objective-C object pointers is strongly " "discouraged">, - InGroup>; + InGroup; +def warn_objc_pointer_masking_performSelector : Warning, + InGroup; def warn_objc_property_default_assign_on_object : Warning< "default property attribute 'assign' not appropriate for non-GC object">, InGroup; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 1d2f39c0da..0c3ae1853a 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -8704,7 +8704,20 @@ static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R, // looks for code trying to introspect into tagged pointers, which // code should generally never do. if (ObjCPointerExpr && isa(OtherExpr->IgnoreParenCasts())) { - S.Diag(OpLoc, diag::warn_objc_pointer_masking) + unsigned Diag = diag::warn_objc_pointer_masking; + // Determine if we are introspecting the result of performSelectorXXX. + const Expr *Ex = ObjCPointerExpr->IgnoreParenCasts(); + // Special case messages to -performSelector and friends, which + // can return non-pointer values boxed in a pointer value. + // Some clients may wish to silence warnings in this subcase. + if (const ObjCMessageExpr *ME = dyn_cast(Ex)) { + Selector S = ME->getSelector(); + StringRef SelArg0 = S.getNameForSlot(0); + if (SelArg0.startswith("performSelector")) + Diag = diag::warn_objc_pointer_masking_performSelector; + } + + S.Diag(OpLoc, Diag) << ObjCPointerExpr->getSourceRange(); } } diff --git a/test/SemaObjC/deprecated-objc-introspection.m b/test/SemaObjC/deprecated-objc-introspection.m index faaef254d5..4f74841458 100644 --- a/test/SemaObjC/deprecated-objc-introspection.m +++ b/test/SemaObjC/deprecated-objc-introspection.m @@ -14,9 +14,11 @@ typedef struct objc_object { id firstobj; struct objc_class *isa; } +- (id)performSelector:(SEL)aSelector;; @end @interface Whatever : NSObject +self; +-(id)foo; @end static void func() { @@ -94,4 +96,9 @@ void testBitmasking(NSObject *p) { (void) (0x1 & ((NSUInteger) p)); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}} (void) (((NSUInteger) p) ^ 0x1); // no-warning (void) (0x1 ^ ((NSUInteger) p)); // no-warning + (void) (0x1 & ((NSUInteger) [p performSelector:@selector(foo)])); // expected-warning {{bitmasking for introspection of Objective-C object pointers is strongly discouraged}} +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-objc-pointer-introspection-performSelector" + (void) (0x1 & ((NSUInteger) [p performSelector:@selector(foo)])); // no-warning +#pragma clang diagnostic pop } \ No newline at end of file