diff options
| -rw-r--r-- | clang/Sema/SemaDecl.cpp | 56 | ||||
| -rw-r--r-- | clang/clang.xcodeproj/project.pbxproj | 2 | ||||
| -rw-r--r-- | clang/test/Sema/DoubleMethod.m | 19 | 
3 files changed, 47 insertions, 30 deletions
diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp index bb100c67ce4..76d1628bfc2 100644 --- a/clang/Sema/SemaDecl.cpp +++ b/clang/Sema/SemaDecl.cpp @@ -1837,6 +1837,7 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl,    bool checkDuplicateMethods =           (isa<ObjcInterfaceDecl>(ClassDecl) || isa<ObjcCategoryDecl>(ClassDecl)           || isa<ObjcProtocolDecl>(ClassDecl)); +  bool checkIdenticalMethods = isa<ObjcImplementationDecl>(ClassDecl);    for (unsigned i = 0; i < allNum; i++ ) {      ObjcMethodDecl *Method = @@ -1844,41 +1845,38 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl,      if (!Method) continue;  // Already issued a diagnostic.      if (Method->isInstance()) { -      if (checkDuplicateMethods) { -        /// Check for instance method of the same name with incompatible types -        const ObjcMethodDecl *&PrevMethod = InsMap[Method->getSelector()]; -        if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) { +      /// Check for instance method of the same name with incompatible types +      const ObjcMethodDecl *&PrevMethod = InsMap[Method->getSelector()]; +      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)  +                              : false; +      if (checkDuplicateMethods && PrevMethod && !match  +          || checkIdenticalMethods && match) {            Diag(Method->getLocation(), diag::error_duplicate_method_decl,                 Method->getSelector().getName());            Diag(PrevMethod->getLocation(), diag::err_previous_declaration); -        } else { -          insMethods.push_back(Method); -          InsMap[Method->getSelector()] = Method; -        } -      } -      else +      } else {          insMethods.push_back(Method); -         -      /// The following allows us to typecheck messages to "id". -      AddInstanceMethodToGlobalPool(Method); -    } else { -      if (checkDuplicateMethods) { -        /// Check for class method of the same name with incompatible types -        const ObjcMethodDecl *&PrevMethod = ClsMap[Method->getSelector()]; -        if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) { -          Diag(Method->getLocation(), diag::error_duplicate_method_decl, -               Method->getSelector().getName()); -          Diag(PrevMethod->getLocation(), diag::err_previous_declaration); -        } else {         -          clsMethods.push_back(Method); -          ClsMap[Method->getSelector()] = Method; -        } +        InsMap[Method->getSelector()] = Method; +        /// The following allows us to typecheck messages to "id". +        AddInstanceMethodToGlobalPool(Method);        } -      else +    } +    else { +      /// Check for class method of the same name with incompatible types +      const ObjcMethodDecl *&PrevMethod = ClsMap[Method->getSelector()]; +      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)  +                              : false; +      if (checkDuplicateMethods && PrevMethod && !match  +          || checkIdenticalMethods && match) { +        Diag(Method->getLocation(), diag::error_duplicate_method_decl, +             Method->getSelector().getName()); +        Diag(PrevMethod->getLocation(), diag::err_previous_declaration); +      } else {          clsMethods.push_back(Method); -         -      /// The following allows us to typecheck messages to "id". -      AddFactoryMethodToGlobalPool(Method); +        ClsMap[Method->getSelector()] = Method; +        /// The following allows us to typecheck messages to "id". +        AddInstanceMethodToGlobalPool(Method); +      }      }    } diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index 33627a1f29d..75d938806b0 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -238,7 +238,7 @@  		84AF36A00CB17A3B00C820A5 /* DeclObjC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DeclObjC.h; path = clang/AST/DeclObjC.h; sourceTree = "<group>"; };  		84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };  		84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; }; -		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; +		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };  		DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };  		DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = "<group>"; };  		DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; }; diff --git a/clang/test/Sema/DoubleMethod.m b/clang/test/Sema/DoubleMethod.m new file mode 100644 index 00000000000..70c7ed55f1e --- /dev/null +++ b/clang/test/Sema/DoubleMethod.m @@ -0,0 +1,19 @@ +// RUN: clang -fsyntax-only -verify %s + +@interface Subclass +{ +    int ivar; +} + +- (void) method; +- (void) method; +@end + +@implementation Subclass +- (void) method {;} // expected-error {{previous declaration is here}} +- (void) method {;} // expected-error {{duplicate declaration of method 'method'}} +@end + +int main (void) { +    return 0; +}  | 

