From: Fariborz Jahanian Date: Mon, 30 Jul 2012 20:52:48 +0000 (+0000) Subject: objective-c arc: ARC IRGen correctly assumes result X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1b0a13e91088f6818016464ffb23616ced820cbc;p=clang objective-c arc: ARC IRGen correctly assumes result type of generated call to super dealloc is 'void' and asserts if user's dealloc is not of 'void type. This rule must be enforced in clang front-end (with a fixit) if this is not the case, instead of asserting in CodeGen. // rdar://11987838 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160993 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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; +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; 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 @end + +@interface Root +@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 +