objc: diagnose duplicate declaration of methods
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 13 Dec 2011 19:40:34 +0000 (19:40 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 13 Dec 2011 19:40:34 +0000 (19:40 +0000)
in classes. // rdar://10535349

llvm-svn: 146504

clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDeclObjC.cpp
clang/test/Parser/enhanced-proto-1.m
clang/test/SemaObjC/DoubleMethod.m
clang/test/SemaObjC/check-dup-decl-methods-1.m
clang/test/SemaObjC/class-conforming-protocol-1.m
clang/test/SemaObjC/enhanced-proto-2.m
clang/test/SemaObjC/undefined-protocol-type-1.m

index fcdd88b..e69312e 100644 (file)
@@ -174,6 +174,7 @@ def : DiagGroup<"strict-overflow">;
 def InvalidOffsetof : DiagGroup<"invalid-offsetof">;
 def : DiagGroup<"strict-prototypes">;
 def StrictSelector : DiagGroup<"strict-selector-match">;
+def MethodDuplicate : DiagGroup<"duplicate-method-match">;
 def SwitchEnum     : DiagGroup<"switch-enum">;
 def Switch         : DiagGroup<"switch", [SwitchEnum]>;
 def Trigraphs      : DiagGroup<"trigraphs">;
index 71fd2ee..941944c 100644 (file)
@@ -488,6 +488,9 @@ def warn_accessor_property_type_mismatch : Warning<
 def note_method_declared_at : Note<"method declared here">;
 def err_setter_type_void : Error<"type of setter must be void">;
 def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
+def warn_duplicate_method_decl : 
+  Warning<"multiple declarations of method %0 found and ignored">, 
+  InGroup<MethodDuplicate>;
 def err_objc_var_decl_inclass : 
     Error<"cannot declare variable inside @interface or @protocol">;
 def error_missing_method_context : Error<
index 8dd484a..5b8f749 100644 (file)
@@ -2210,8 +2210,14 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
           Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
         Method->setInvalidDecl();
       } else {
-        if (PrevMethod)
+        if (PrevMethod) {
           Method->setAsRedeclaration(PrevMethod);
+          if (!Context.getSourceManager().isInSystemHeader(
+                 Method->getLocation()))
+            Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
+              << Method->getDeclName();
+          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
+        }
         InsMap[Method->getSelector()] = Method;
         /// The following allows us to typecheck messages to "id".
         AddInstanceMethodToGlobalPool(Method);
@@ -2231,8 +2237,14 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
         Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
         Method->setInvalidDecl();
       } else {
-        if (PrevMethod)
+        if (PrevMethod) {
           Method->setAsRedeclaration(PrevMethod);
+          if (!Context.getSourceManager().isInSystemHeader(
+                 Method->getLocation()))
+            Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
+              << Method->getDeclName();
+          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
+        }
         ClsMap[Method->getSelector()] = Method;
         /// The following allows us to typecheck messages to "Class".
         AddFactoryMethodToGlobalPool(Method);
index a3819f3..fa6e413 100644 (file)
@@ -4,7 +4,7 @@
 @optional
 - (void) FOO;
 @optional
-- (void) FOO;
+- (void) FOO1;
 @required 
 - (void) REQ;
 @optional
index 98aa699..6c7e907 100644 (file)
@@ -5,8 +5,8 @@
     int ivar;
 }
 
-- (void) method;
-- (void) method;
+- (void) method; // expected-note {{previous declaration is here}}
+- (void) method; // expected-warning {{multiple declarations of method 'method' found and ignored}}
 @end
 
 @implementation Subclass
index 1dd6446..667c381 100644 (file)
@@ -10,8 +10,8 @@
 @interface class1 : SUPER
 - (int) meth;  // expected-note {{previous declaration is here}}
 - (int*) meth; // expected-error {{duplicate declaration of method 'meth'}}
-- (T*) meth1;  
-- (T*) meth1;
+- (T*) meth1;   // expected-note {{previous declaration is here}}
+- (T*) meth1;   // expected-warning {{multiple declarations of method 'meth1' found and ignored}}
 + (T*) meth1;
 @end
 
index 43ea6d3..5d4e86d 100644 (file)
@@ -8,12 +8,11 @@
 - (INTF*) METH1;       // expected-note {{previous declaration is here}}
 - (INTF<P1>*) METH1;   // expected-error {{duplicate declaration of method 'METH1'}}
 
-- (INTF<P1,P2>*) METH2;
 - (INTF<P2,P1>*) METH2;  // expected-note {{previous declaration is here}}
 - (INTF<P2,P1,P3>*) METH2;  // expected-error {{duplicate declaration of method 'METH2'}}
 
-- (INTF<P2,P1,P3>*) METH3;
-- (INTF<P3,P1,P2, P3>*) METH3;
+- (INTF<P2,P1,P3>*) METH3; // expected-note {{previous declaration is here}}
+- (INTF<P3,P1,P2, P3>*) METH3; // expected-warning {{multiple declarations of method 'METH3' found and ignored}}
 
 @end
 
index da7875c..de1d56a 100644 (file)
@@ -4,7 +4,7 @@
 @optional
 - (void) FOO;
 @optional
-- (void) FOO;
+- (void) FOO1;
 @optional 
 - (void) REQ;
 @optional
index 3be4425..f1a0802 100644 (file)
@@ -5,5 +5,5 @@
 
 @interface T
 - (T<p2, p3, p1, p4>*) meth;  // expected-error {{cannot find protocol declaration for 'p3'}}
-- (T<p2, p3, p1, p4>*) meth;  // expected-error {{cannot find protocol declaration for 'p3'}}
+- (T<p2, p3, p1, p4>*) meth1;  // expected-error {{cannot find protocol declaration for 'p3'}}
 @end