aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/SemaDeclObjC.cpp16
-rw-r--r--test/Parser/enhanced-proto-1.m2
-rw-r--r--test/SemaObjC/DoubleMethod.m4
-rw-r--r--test/SemaObjC/check-dup-decl-methods-1.m4
-rw-r--r--test/SemaObjC/class-conforming-protocol-1.m5
-rw-r--r--test/SemaObjC/enhanced-proto-2.m2
-rw-r--r--test/SemaObjC/undefined-protocol-type-1.m2
9 files changed, 27 insertions, 12 deletions
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index fcdd88b7cd..e69312e37a 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -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">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 71fd2ee653..941944c8a4 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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<
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 8dd484a3b5..5b8f749db7 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -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);
diff --git a/test/Parser/enhanced-proto-1.m b/test/Parser/enhanced-proto-1.m
index a3819f3a19..fa6e4138f1 100644
--- a/test/Parser/enhanced-proto-1.m
+++ b/test/Parser/enhanced-proto-1.m
@@ -4,7 +4,7 @@
@optional
- (void) FOO;
@optional
-- (void) FOO;
+- (void) FOO1;
@required
- (void) REQ;
@optional
diff --git a/test/SemaObjC/DoubleMethod.m b/test/SemaObjC/DoubleMethod.m
index 98aa699a0f..6c7e907cb5 100644
--- a/test/SemaObjC/DoubleMethod.m
+++ b/test/SemaObjC/DoubleMethod.m
@@ -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
diff --git a/test/SemaObjC/check-dup-decl-methods-1.m b/test/SemaObjC/check-dup-decl-methods-1.m
index 1dd6446e84..667c381145 100644
--- a/test/SemaObjC/check-dup-decl-methods-1.m
+++ b/test/SemaObjC/check-dup-decl-methods-1.m
@@ -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
diff --git a/test/SemaObjC/class-conforming-protocol-1.m b/test/SemaObjC/class-conforming-protocol-1.m
index 43ea6d34d1..5d4e86ddfe 100644
--- a/test/SemaObjC/class-conforming-protocol-1.m
+++ b/test/SemaObjC/class-conforming-protocol-1.m
@@ -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
diff --git a/test/SemaObjC/enhanced-proto-2.m b/test/SemaObjC/enhanced-proto-2.m
index da7875cfa7..de1d56a2d7 100644
--- a/test/SemaObjC/enhanced-proto-2.m
+++ b/test/SemaObjC/enhanced-proto-2.m
@@ -4,7 +4,7 @@
@optional
- (void) FOO;
@optional
-- (void) FOO;
+- (void) FOO1;
@optional
- (void) REQ;
@optional
diff --git a/test/SemaObjC/undefined-protocol-type-1.m b/test/SemaObjC/undefined-protocol-type-1.m
index 3be4425cdc..f1a08024b2 100644
--- a/test/SemaObjC/undefined-protocol-type-1.m
+++ b/test/SemaObjC/undefined-protocol-type-1.m
@@ -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