r182964 - Objective-C: Implements gcc's -Wselector option

Fariborz Jahanian fjahanian at apple.com
Thu May 30 14:48:58 PDT 2013


Author: fjahanian
Date: Thu May 30 16:48:58 2013
New Revision: 182964

URL: http://llvm.org/viewvc/llvm-project?rev=182964&view=rev
Log:
Objective-C: Implements gcc's -Wselector option
which diagnoses type mismatches of identical 
selectors declared in classes throughout.
// rdar://14007194

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/test/PCH/Inputs/chain-selectors2.h
    cfe/trunk/test/SemaObjC/selector-3.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=182964&r1=182963&r2=182964&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Thu May 30 16:48:58 2013
@@ -338,7 +338,8 @@ def AutomaticReferenceCounting : DiagGro
 def ARCRepeatedUseOfWeakMaybe : DiagGroup<"arc-maybe-repeated-use-of-weak">;
 def ARCRepeatedUseOfWeak : DiagGroup<"arc-repeated-use-of-weak",
                                      [ARCRepeatedUseOfWeakMaybe]>;
-def Selector : DiagGroup<"selector">;
+def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">;
+def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>;
 def Protocol : DiagGroup<"protocol">;
 def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
 def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=182964&r1=182963&r2=182964&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 30 16:48:58 2013
@@ -824,6 +824,8 @@ def warn_auto_implicit_atomic_property :
   InGroup<ImplicitAtomic>, DefaultIgnore;
 def warn_unimplemented_selector:  Warning<
   "creating selector for nonexistent method %0">, InGroup<Selector>, DefaultIgnore;
+def warning_multiple_selectors: Warning<
+  "multiple selectors named %0 found">, InGroup<SelectorTypeMismatch>, DefaultIgnore;
 def warn_unimplemented_protocol_method : Warning<
   "method %0 in protocol not implemented">, InGroup<Protocol>;
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=182964&r1=182963&r2=182964&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu May 30 16:48:58 2013
@@ -2669,6 +2669,11 @@ public:
                                     warn, /*instance*/false);
   }
 
+  /// DiagnoseMismatchedMethodsInGlobalPool - This routine goes through list of
+  /// methods in global pool and issues diagnostic on identical selectors which
+  /// have mismathched types.
+  void DiagnoseMismatchedMethodsInGlobalPool();
+  
   /// LookupImplementedMethodInGlobalPool - Returns the method which has an
   /// implementation.
   ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel);

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=182964&r1=182963&r2=182964&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu May 30 16:48:58 2013
@@ -2271,7 +2271,52 @@ ObjCMethodDecl *Sema::LookupImplementedM
   return 0;
 }
 
-/// DiagnoseDuplicateIvars - 
+static void
+HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
+                                              ObjCMethodList &MethList) {
+  ObjCMethodList *M = &MethList;
+  ObjCMethodDecl *TargetMethod = M->Method;
+  while (TargetMethod &&
+         isa<ObjCImplDecl>(TargetMethod->getDeclContext())) {
+    M = M->getNext();
+    TargetMethod = M ? M->Method : 0;
+  }
+  if (!TargetMethod)
+    return;
+  bool FirstTime = true;
+  for (M = M->getNext(); M; M=M->getNext()) {
+    ObjCMethodDecl *MatchingMethodDecl = M->Method;
+    if (isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()))
+      continue;
+    if (!S.MatchTwoMethodDeclarations(TargetMethod,
+                                      MatchingMethodDecl, Sema::MMS_loose)) {
+      if (FirstTime) {
+        FirstTime = false;
+        S.Diag(TargetMethod->getLocation(), diag::warning_multiple_selectors)
+        << TargetMethod->getSelector();
+      }
+      S.Diag(MatchingMethodDecl->getLocation(), diag::note_also_found);
+    }
+  }
+}
+
+void Sema::DiagnoseMismatchedMethodsInGlobalPool() {
+  unsigned DIAG = diag::warning_multiple_selectors;
+  if (Diags.getDiagnosticLevel(DIAG, SourceLocation())
+      == DiagnosticsEngine::Ignored)
+    return;
+  for (GlobalMethodPool::iterator b = MethodPool.begin(),
+       e = MethodPool.end(); b != e; b++) {
+    // first, instance methods
+    ObjCMethodList &InstMethList = b->second.first;
+    HelperToDiagnoseMismatchedMethodsInGlobalPool(*this, InstMethList);
+    // second, instance methods
+    ObjCMethodList &ClsMethList = b->second.second;
+    HelperToDiagnoseMismatchedMethodsInGlobalPool(*this, ClsMethList);
+  }
+}
+
+/// DiagnoseDuplicateIvars -
 /// Check for duplicate ivars in the entire class at the start of 
 /// \@implementation. This becomes necesssary because class extension can
 /// add ivars to a class in random order which will not be known until
@@ -3294,6 +3339,8 @@ void Sema::DiagnoseUseOfUnimplementedSel
       ReferencedSelectors[Sels[I].first] = Sels[I].second;
   }
   
+  DiagnoseMismatchedMethodsInGlobalPool();
+  
   // Warning will be issued only when selector table is
   // generated (which means there is at lease one implementation
   // in the TU). This is to match gcc's behavior.

Modified: cfe/trunk/test/PCH/Inputs/chain-selectors2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/Inputs/chain-selectors2.h?rev=182964&r1=182963&r2=182964&view=diff
==============================================================================
--- cfe/trunk/test/PCH/Inputs/chain-selectors2.h (original)
+++ cfe/trunk/test/PCH/Inputs/chain-selectors2.h Thu May 30 16:48:58 2013
@@ -1,6 +1,6 @@
 @interface Y
   -(void)f;
-  -(double)f2;
+  -(void)f2;
   -(void)e;
 @end
 

Modified: cfe/trunk/test/SemaObjC/selector-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/selector-3.m?rev=182964&r1=182963&r2=182964&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/selector-3.m (original)
+++ cfe/trunk/test/SemaObjC/selector-3.m Thu May 30 16:48:58 2013
@@ -81,3 +81,32 @@ extern SEL MySelector(SEL s);
   }
 }
 @end
+
+// rdar://14007194
+ at interface UxTechTest : NSObject
+- (int) invalidate : (id)Arg; // expected-warning {{multiple selectors named 'invalidate:' found}}
++ (int) C_invalidate : (int)arg; // expected-warning {{multiple selectors named 'C_invalidate:' found}}
+ at end
+
+ at interface UxTechTest(CAT)
+- (char) invalidate : (int)arg; // expected-note {{also found}}
++ (int) C_invalidate : (char)arg; // expected-note {{also found}}
+ at end
+
+ at interface NSPort : NSObject
+- (double) invalidate : (void*)Arg1; // expected-note {{also found}}
++ (int) C_invalidate : (id*)arg; // expected-note {{also found}}
+ at end
+
+
+ at interface USEText : NSPort
+- (int) invalidate : (int)arg; // expected-note {{also found}}
+ at end
+
+ at implementation USEText
+- (int) invalidate :(int) arg { return 0; }
+ at end
+
+ at interface USETextSub : USEText
+- (int) invalidate : (id)arg;
+ at end





More information about the cfe-commits mailing list