]> granicus.if.org Git - clang/commitdiff
Tweak -Wdeprecated-objc-pointer-introspection to have a subgroup for results of using...
authorTed Kremenek <kremenek@apple.com>
Mon, 24 Jun 2013 21:35:39 +0000 (21:35 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 24 Jun 2013 21:35:39 +0000 (21:35 +0000)
-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 <rdar://problem/14147304>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184789 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/SemaObjC/deprecated-objc-introspection.m

index 31b0b5623efb75cc43842cc26e1823b1abc2ff3d..c1734506bce6f8f63140eba338f31061a0aa314e 100644 (file)
@@ -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">;
index 5d7d2372bdc4b5fb6b381bbb517d5c393c97d728..bb532eb04c651cb456d4169f21f38d690fc52fd7 100644 (file)
@@ -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<DiagGroup<"deprecated-objc-pointer-introspection">>;
+  InGroup<ObjCPointerIntrospect>;
+def warn_objc_pointer_masking_performSelector : Warning<warn_objc_pointer_masking.Text>,
+  InGroup<ObjCPointerIntrospectPerformSelector>;
 def warn_objc_property_default_assign_on_object : Warning<
   "default property attribute 'assign' not appropriate for non-GC object">,
   InGroup<ObjCPropertyNoAttribute>;
index 1d2f39c0da3b86e51dc3e66d846cebac52e6d26a..0c3ae1853aff5d020cb920daadacccc5b49ffbdc 100644 (file)
@@ -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<IntegerLiteral>(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<ObjCMessageExpr>(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();
   }
 }
index faaef254d5962bf41894f335906ffda173eb4714..4f7484145865d7fb15b8f4c51c1303f25903036c 100644 (file)
@@ -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