diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2008-12-05 01:35:25 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2008-12-05 01:35:25 +0000 |
commit | de7394157c3f83af55053128178aa71bdb08101c (patch) | |
tree | b54eb65619d9cfd018c5766f8425e0b9a472680e | |
parent | f3d416267ec92cf28da11a79b47383179b77c5d0 (diff) |
Patch for diagnosing type mismatch between
methods in class and its implementation.
This is work in progress.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60573 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 28 | ||||
-rw-r--r-- | test/SemaObjC/comptypes-a.m | 14 | ||||
-rw-r--r-- | test/SemaObjC/method-def-1.m | 2 |
3 files changed, 31 insertions, 13 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index b3afd78fc7..9da662e476 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -643,6 +643,34 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl, E = IDecl->instmeth_end(); I != E; ++I) if (!(*I)->isSynthesized() && !InsMap.count((*I)->getSelector())) WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl); + else if (!(*I)->isSynthesized()){ + bool err = false; + ObjCMethodDecl *ImpMethodDecl = + IMPDecl->getInstanceMethod((*I)->getSelector()); + ObjCMethodDecl *IntfMethodDecl = + IDecl->getInstanceMethod((*I)->getSelector()); + QualType ImpMethodQType = + Context.getCanonicalType(ImpMethodDecl->getResultType()); + QualType IntfMethodQType = + Context.getCanonicalType(IntfMethodDecl->getResultType()); + if (!Context.typesAreCompatible(IntfMethodQType, ImpMethodQType)) + err = true; + else for (ObjCMethodDecl::param_iterator IM=ImpMethodDecl->param_begin(), + IF=IntfMethodDecl->param_begin(), + EM=ImpMethodDecl->param_end(); IM!=EM; ++IM, IF++) { + ImpMethodQType = Context.getCanonicalType((*IM)->getType()); + IntfMethodQType = Context.getCanonicalType((*IF)->getType()); + if (!Context.typesAreCompatible(IntfMethodQType, ImpMethodQType)) { + err = true; + break; + } + } + if (err) { + Diag(ImpMethodDecl->getLocation(), diag::err_conflicting_types) + << ImpMethodDecl->getDeclName(); + Diag(IntfMethodDecl->getLocation(), diag::note_previous_definition); + } + } llvm::DenseSet<Selector> ClsMap; // Check and see if class methods in class interface have been diff --git a/test/SemaObjC/comptypes-a.m b/test/SemaObjC/comptypes-a.m index bd8a7490c4..f00369f5ca 100644 --- a/test/SemaObjC/comptypes-a.m +++ b/test/SemaObjC/comptypes-a.m @@ -15,25 +15,15 @@ NSInteger codeAssistantCaseCompareItems(id<PBXCompletionItem> a, id<PBXCompletio { } -#if 0 -FIXME: clang needs to compare each method prototype with its definition (see below). - -GCC produces the following correct warnning: -[snaroff:llvm/tools/clang] snarofflocal% cc -c test/Sema/objc-types-compatible.m -test/Sema/objc-types-compatible.m: In function ‘-[TedWantsToVerifyObjCDoesTheRightThing compareThis:withThat:]’: -test/Sema/objc-types-compatible.m:26: warning: conflicting types for ‘-(id)compareThis:(id <PBXCompletionItem>)a withThat:(id <PBXCompletionItem>)b’ -test/Sema/objc-types-compatible.m:20: warning: previous declaration of ‘-(id)compareThis:(int)a withThat:(id)b’ -#endif - @interface TedWantsToVerifyObjCDoesTheRightThing -- compareThis:(int)a withThat:(id)b; +- compareThis:(int)a withThat:(id)b; // expected-note {{previous definition is here}} @end @implementation TedWantsToVerifyObjCDoesTheRightThing -- compareThis:(id<PBXCompletionItem>)a withThat:(id<PBXCompletionItem>)b { +- compareThis:(id<PBXCompletionItem>)a withThat:(id<PBXCompletionItem>)b { // expected-error {{conflicting types for 'compareThis:withThat:'}} return self; } diff --git a/test/SemaObjC/method-def-1.m b/test/SemaObjC/method-def-1.m index c1cd6294b7..7948eed580 100644 --- a/test/SemaObjC/method-def-1.m +++ b/test/SemaObjC/method-def-1.m @@ -16,6 +16,6 @@ @implementation MyClass - (void)myMethod { } -- (void)myMethod2 { } +- (vid)myMethod2 { } // expected-error {{expected a type}} @end |