diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 19 | ||||
-rw-r--r-- | test/ARCMT/releases-driver.m | 3 | ||||
-rw-r--r-- | test/ARCMT/releases-driver.m.result | 3 | ||||
-rw-r--r-- | test/ARCMT/releases.m | 3 | ||||
-rw-r--r-- | test/ARCMT/releases.m.result | 3 | ||||
-rw-r--r-- | test/SemaObjC/dealloc.m | 25 |
7 files changed, 48 insertions, 11 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index a58f901cc3..263a4aef94 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -731,6 +731,9 @@ def warn_objc_property_attr_mutually_exclusive : Warning< def warn_objc_missing_super_dealloc : Warning< "method possibly missing a [super dealloc] call">, InGroup<ObjCMissingSuperCalls>; +def error_dealloc_bad_result_type : Error< + "dealloc return type must be correctly specified as 'void' under ARC, " + "instead of %0">; def warn_objc_missing_super_finalize : Warning< "method possibly missing a [super finalize] call">, InGroup<ObjCMissingSuperCalls>; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 17c34a239d..52ca335150 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -197,7 +197,6 @@ static bool CheckARCMethodDecl(Sema &S, ObjCMethodDecl *method) { ObjCMethodFamily family = method->getMethodFamily(); switch (family) { case OMF_None: - case OMF_dealloc: case OMF_finalize: case OMF_retain: case OMF_release: @@ -207,6 +206,24 @@ static bool CheckARCMethodDecl(Sema &S, ObjCMethodDecl *method) { case OMF_performSelector: return false; + case OMF_dealloc: + if (!S.Context.hasSameType(method->getResultType(), S.Context.VoidTy)) { + SourceRange ResultTypeRange; + if (const TypeSourceInfo *ResultTypeInfo + = method->getResultTypeSourceInfo()) + ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange(); + if (ResultTypeRange.isInvalid()) + S.Diag(method->getLocation(), diag::error_dealloc_bad_result_type) + << method->getResultType() + << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)"); + else + S.Diag(method->getLocation(), diag::error_dealloc_bad_result_type) + << method->getResultType() + << FixItHint::CreateReplacement(ResultTypeRange, "void"); + return true; + } + return false; + case OMF_init: // If the method doesn't obey the init rules, don't bother annotating it. if (S.checkInitMethod(method, QualType())) diff --git a/test/ARCMT/releases-driver.m b/test/ARCMT/releases-driver.m index b75432ac23..7b1d2fb8e5 100644 --- a/test/ARCMT/releases-driver.m +++ b/test/ARCMT/releases-driver.m @@ -53,9 +53,8 @@ void func(Foo *p) { @end @implementation Baz -- dealloc { +- (void) dealloc { [_foo release]; - return 0; } @end diff --git a/test/ARCMT/releases-driver.m.result b/test/ARCMT/releases-driver.m.result index 70c0aecaf4..4c864bd2a8 100644 --- a/test/ARCMT/releases-driver.m.result +++ b/test/ARCMT/releases-driver.m.result @@ -49,9 +49,6 @@ void func(Foo *p) { @end @implementation Baz -- dealloc { - return 0; -} @end #define RELEASE_MACRO(x) [x release] diff --git a/test/ARCMT/releases.m b/test/ARCMT/releases.m index 867fab9cec..55008959ef 100644 --- a/test/ARCMT/releases.m +++ b/test/ARCMT/releases.m @@ -58,9 +58,8 @@ void func(Foo *p) { @end @implementation Baz -- dealloc { +- (void) dealloc { [_foo release]; - return 0; } @end diff --git a/test/ARCMT/releases.m.result b/test/ARCMT/releases.m.result index 556610ab2a..473750e4e8 100644 --- a/test/ARCMT/releases.m.result +++ b/test/ARCMT/releases.m.result @@ -54,9 +54,6 @@ void func(Foo *p) { @end @implementation Baz -- dealloc { - return 0; -} @end void block_test(Foo *p) { diff --git a/test/SemaObjC/dealloc.m b/test/SemaObjC/dealloc.m new file mode 100644 index 0000000000..feafafd375 --- /dev/null +++ b/test/SemaObjC/dealloc.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// rdar://11987838 + +@protocol NSObject +- dealloc; // expected-error {{return type must be correctly specified as 'void' under ARC, instead of 'id'}} +// CHECK: fix-it:"{{.*}}":{6:3-6:3}:"(void)" +@end + +@protocol Foo <NSObject> @end + +@interface Root <Foo> +@end + +@interface Baz : Root { +} +@end + +@implementation Baz +- (id) dealloc { // expected-error {{return type must be correctly specified as 'void' under ARC, instead of 'id'}} +// CHECK: fix-it:"{{.*}}":{20:5-20:7}:"void" +} + +@end + |