]> granicus.if.org Git - clang/commitdiff
objective-c arc: ARC IRGen correctly assumes result
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 30 Jul 2012 20:52:48 +0000 (20:52 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 30 Jul 2012 20:52:48 +0000 (20:52 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclObjC.cpp
test/ARCMT/releases-driver.m
test/ARCMT/releases-driver.m.result
test/ARCMT/releases.m
test/ARCMT/releases.m.result
test/SemaObjC/dealloc.m [new file with mode: 0644]

index a58f901cc3e13ec8c294ea805b5f6c3aea76b72a..263a4aef946eb339c30c1365f0ecf65b152c8d70 100644 (file)
@@ -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>;
index 17c34a239d5cf44a2b5ec424acd1af10a2aa8b38..52ca3351500a4a08b2158de7c1b119b693aee99e 100644 (file)
@@ -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()))
index b75432ac2318840547c05a3b26ccd7810ce27ea0..7b1d2fb8e5b25e13aa9aa7b5f27849ea2b315a84 100644 (file)
@@ -53,9 +53,8 @@ void func(Foo *p) {
 @end
 
 @implementation Baz
-- dealloc {
+- (void) dealloc {
   [_foo release];
-  return 0;
 }
 @end
 
index 70c0aecaf4755510fc40e4d5b65fa21b80b34e7f..4c864bd2a874abc09afe9a915b44c39d771cb491 100644 (file)
@@ -49,9 +49,6 @@ void func(Foo *p) {
 @end
 
 @implementation Baz
-- dealloc {
-  return 0;
-}
 @end
 
 #define RELEASE_MACRO(x) [x release]
index 867fab9cec741e9146699a8ca66d7c198b3f93c1..55008959efc4e428199a43f928f2ab1fb64d04cd 100644 (file)
@@ -58,9 +58,8 @@ void func(Foo *p) {
 @end
 
 @implementation Baz
-- dealloc {
+- (void) dealloc {
   [_foo release];
-  return 0;
 }
 @end
 
index 556610ab2a53484ece314125c2d4be5b7bd33430..473750e4e899b56b6618010dadf48fe353d5b5f0 100644 (file)
@@ -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 (file)
index 0000000..feafafd
--- /dev/null
@@ -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
+