]> granicus.if.org Git - clang/commitdiff
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

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

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

index fcdd88b7cdd72324e0b3d2b644496a3b9f041820..e69312e37a24ee63faa1d59333bd36de59576dbb 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 71fd2ee653712bf7151ab0449f18b6c2904fd908..941944c8a467c3083fb16dc075a33153376f7491 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 8dd484a3b5598c72f9cb07dbcad16152ba257375..5b8f749db784d8e3bcdf78078ad7b23cf5a4cfb4 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 a3819f3a19589346fa1a2db514cd035eb57eeae7..fa6e4138f1c1eb7069a9a3f124cfdf3a5d588820 100644 (file)
@@ -4,7 +4,7 @@
 @optional
 - (void) FOO;
 @optional
-- (void) FOO;
+- (void) FOO1;
 @required 
 - (void) REQ;
 @optional
index 98aa699a0fce429bb09d20a276e5026dda2006be..6c7e907cb58a9456df3af5dcb16911c25b460d5e 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 1dd6446e84ca0d51e01578f187084f5ec7dfda3b..667c38114564e6d449622749cdcb32d5f5910015 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 43ea6d34d1bbb21f9963511cf67987be91b5ba12..5d4e86ddfe4113a99988f819e0f26ed3e7568a45 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 da7875cfa7c72fbf759be8bc304cb9f538734c9e..de1d56a2d773fd96e94c4352a65c7bd4b1524402 100644 (file)
@@ -4,7 +4,7 @@
 @optional
 - (void) FOO;
 @optional
-- (void) FOO;
+- (void) FOO1;
 @optional 
 - (void) REQ;
 @optional
index 3be4425cdcec089635fae40f08fab3b164bfee8b..f1a08024b251e822d5c6ddac65960e9bb10a1f50 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