From fe6b0dc94a5279f33aba9a3bc0237c9841be3d43 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Tue, 21 Oct 2008 10:37:50 +0000 Subject: [PATCH] Fix clang-on-xcode: [sema] multiple method warning is over enthusiastic. Fix warnings for ambiguous message send swamp other warnings. Reworked Sema::MatchTwoMethodDeclarations() to optionally match based on method size and alignment (the default in GCC). Changed Sema::LookupInstanceMethodInGlobalPool() to use this feature. Added -Wno-struct-selector-match to driver, however didn't hook it up yet. Added a FIXME that says this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57898 91177308-0d34-0410-b5e6-96231b3b80d8 --- Driver/clang.cpp | 5 ++++ lib/Sema/Sema.h | 3 ++- lib/Sema/SemaDeclObjC.cpp | 46 ++++++++++++++++++++++++++------- test/SemaObjC/method-lookup-3.m | 12 ++++----- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/Driver/clang.cpp b/Driver/clang.cpp index fcd4d5ab72..c2afe5b622 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -595,6 +595,11 @@ static llvm::cl::opt WarnImplicitFunctionDeclaration("Wimplicit-function-declaration", llvm::cl::desc("Warn about uses of implicitly defined functions")); +static llvm::cl::opt +WarnNoStrictSelectorMatch("Wno-strict-selector-match", + llvm::cl::desc("Do not warn about duplicate methods that have the same size and alignment"), + llvm::cl::init(true)); + /// InitializeDiagnostics - Initialize the diagnostic object, based on the /// current command line option settings. static void InitializeDiagnostics(Diagnostic &Diags) { diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index e9e1ad1568..796ba4ed04 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -411,7 +411,8 @@ private: /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns /// true, or false, accordingly. bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, - const ObjCMethodDecl *PrevMethod); + const ObjCMethodDecl *PrevMethod, + bool matchBasedOnSizeAndAlignment = false); /// AddInstanceMethodToGlobalPool - All instance methods in a translation /// unit are added to a global pool. This allows us to efficiently associate diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 6375d91448..d5fa8848c3 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -739,17 +739,37 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, /// returns true, or false, accordingly. /// TODO: Handle protocol list; such as id in type comparisons bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, - const ObjCMethodDecl *PrevMethod) { - if (Context.getCanonicalType(Method->getResultType()) != - Context.getCanonicalType(PrevMethod->getResultType())) - return false; - for (unsigned i = 0, e = Method->getNumParams(); i != e; ++i) { - ParmVarDecl *ParamDecl = Method->getParamDecl(i); - ParmVarDecl *PrevParamDecl = PrevMethod->getParamDecl(i); - if (Context.getCanonicalType(ParamDecl->getType()) != - Context.getCanonicalType(PrevParamDecl->getType())) + const ObjCMethodDecl *PrevMethod, + bool matchBasedOnSizeAndAlignment) { + QualType T1 = Context.getCanonicalType(Method->getResultType()); + QualType T2 = Context.getCanonicalType(PrevMethod->getResultType()); + + if (T1 != T2) { + // The result types are different. + if (!matchBasedOnSizeAndAlignment) + return false; + // Incomplete types don't have a size and alignment. + if (T1->isIncompleteType() || T2->isIncompleteType()) + return false; + // Check is based on size and alignment. + if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2)) return false; } + for (unsigned i = 0, e = Method->getNumParams(); i != e; ++i) { + T1 = Context.getCanonicalType(Method->getParamDecl(i)->getType()); + T2 = Context.getCanonicalType(PrevMethod->getParamDecl(i)->getType()); + if (T1 != T2) { + // The result types are different. + if (!matchBasedOnSizeAndAlignment) + return false; + // Incomplete types don't have a size and alignment. + if (T1->isIncompleteType() || T2->isIncompleteType()) + return false; + // Check is based on size and alignment. + if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2)) + return false; + } + } return true; } @@ -776,11 +796,19 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) { } } +// FIXME: Finish implementing -Wno-struct-selector-match. ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R) { ObjCMethodList &MethList = InstanceMethodPool[Sel]; + bool issueWarning = false; if (MethList.Method && MethList.Next) { + for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next) + // This checks if the methods differ by size & alignment. + if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true)) + issueWarning = true; + } + if (issueWarning && (MethList.Method && MethList.Next)) { Diag(R.getBegin(), diag::warn_multiple_method_decl, Sel.getName(), R); Diag(MethList.Method->getLocStart(), diag::warn_using_decl, MethList.Method->getSourceRange()); diff --git a/test/SemaObjC/method-lookup-3.m b/test/SemaObjC/method-lookup-3.m index a1815fa386..25299ca6d3 100644 --- a/test/SemaObjC/method-lookup-3.m +++ b/test/SemaObjC/method-lookup-3.m @@ -22,9 +22,9 @@ typedef struct { int x; } Alternate; -(void) x; // expected-warning{{also found}} -(void) y; // expected-warning{{also found}} -(void) z; // expected-warning{{also found}} --(void) setX: (INTERFERE_TYPE) arg; // expected-warning{{also found}} --(void) setY: (INTERFERE_TYPE) arg; // expected-warning{{also found}} --(void) setZ: (INTERFERE_TYPE) arg; // expected-warning{{also found}} +-(void) setX: (INTERFERE_TYPE) arg; +-(void) setY: (INTERFERE_TYPE) arg; +-(void) setZ: (INTERFERE_TYPE) arg; @end void f0(id a0) { @@ -40,13 +40,13 @@ void f2(id a0) { } void f3(id a0, Abstract *a1) { - [ a0 setX: a1]; // expected-warning {{multiple methods named 'setX:' found}} + [ a0 setX: a1]; } void f4(id a0, Abstract *a1) { - [ a0 setY: a1]; // expected-warning {{multiple methods named 'setY:' found}} + [ a0 setY: a1]; } void f5(id a0, Abstract *a1) { - [ a0 setZ: a1]; // expected-warning {{multiple methods named 'setZ:' found}} + [ a0 setZ: a1]; } -- 2.40.0