diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 96ce0daea1e078c85794cd869047caa41272b841..c7b188d096ef83e3bbe666317b8b7cf1255b974b 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1851,8 +1851,11 @@ public: bool &IncompleteImpl, unsigned DiagID); void WarnConflictingTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, - bool IsProtocolMethodDecl, - bool IsDeclaration = false); + bool IsProtocolMethodDecl); + + void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, + ObjCMethodDecl *Overridden, + bool IsProtocolMethodDecl); /// WarnExactTypedMethods - This routine issues a warning if method /// implementation declaration matches exactly that of its declaration. diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index af2eb1287b3ca10b19dca5279dc27adc0ad6104b..21b2622b4a3521bdb9905d7e7ed367e44474a871 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1331,34 +1331,51 @@ static bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl, void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, ObjCMethodDecl *MethodDecl, - bool IsProtocolMethodDecl, - bool IsOverridingMode) { + bool IsProtocolMethodDecl) { if (getLangOptions().ObjCAutoRefCount && - !IsOverridingMode && checkMethodFamilyMismatch(*this, ImpMethodDecl, MethodDecl)) return; CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl, - IsProtocolMethodDecl, IsOverridingMode, + IsProtocolMethodDecl, false, true); for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(), IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(); IM != EM; ++IM, ++IF) { CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF, - IsProtocolMethodDecl, IsOverridingMode, true); + IsProtocolMethodDecl, false, true); } if (ImpMethodDecl->isVariadic() != MethodDecl->isVariadic()) { - if (IsOverridingMode) - Diag(ImpMethodDecl->getLocation(), - diag::warn_conflicting_overriding_variadic); - else - Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_variadic); + Diag(ImpMethodDecl->getLocation(), + diag::warn_conflicting_variadic); Diag(MethodDecl->getLocation(), diag::note_previous_declaration); } } +void Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method, + ObjCMethodDecl *Overridden, + bool IsProtocolMethodDecl) { + + CheckMethodOverrideReturn(*this, Method, Overridden, + IsProtocolMethodDecl, true, + true); + + for (ObjCMethodDecl::param_iterator IM = Method->param_begin(), + IF = Overridden->param_begin(), EM = Method->param_end(); + IM != EM; ++IM, ++IF) { + CheckMethodOverrideParam(*this, Method, Overridden, *IM, *IF, + IsProtocolMethodDecl, true, true); + } + + if (Method->isVariadic() != Overridden->isVariadic()) { + Diag(Method->getLocation(), + diag::warn_conflicting_overriding_variadic); + Diag(Overridden->getLocation(), diag::note_previous_declaration); + } +} + /// WarnExactTypedMethods - This routine issues a warning if method /// implementation declaration matches exactly that of its declaration. void Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl, @@ -2677,10 +2694,9 @@ Decl *Sema::ActOnMethodDeclaration( // Check for overriding methods if (isa<ObjCInterfaceDecl>(ObjCMethod->getDeclContext()) || - isa<ObjCImplementationDecl>(ObjCMethod->getDeclContext())) { - WarnConflictingTypedMethods(ObjCMethod, overridden, - isa<ObjCProtocolDecl>(overridden->getDeclContext()), true); - } + isa<ObjCImplementationDecl>(ObjCMethod->getDeclContext())) + CheckConflictingOverridingMethod(ObjCMethod, overridden, + isa<ObjCProtocolDecl>(overridden->getDeclContext())); } bool ARCError = false;