]> granicus.if.org Git - clang/commitdiff
objc-arc: provide a warning when 'receiver' of a message is 'weak'
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 4 Apr 2012 20:05:25 +0000 (20:05 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 4 Apr 2012 20:05:25 +0000 (20:05 +0000)
in arc mode and opted-in with -Wreceiver-is-weak flag.
// rdar://10225276

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154042 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprObjC.cpp
test/SemaObjC/weak-receiver-warn.m [new file with mode: 0644]

index 9bd3ec165b1223bf9ce81d9d72a85ff086be6ad1..480ba958a1338d19a2adca3b99f821372a495733 100644 (file)
@@ -652,6 +652,9 @@ def warn_arc_perform_selector_leaks : Warning<
   InGroup<DiagGroup<"arc-performSelector-leaks">>;
 def err_gc_weak_property_strong_type : Error<
   "weak attribute declared on a __strong type property in GC mode">;
+def warn_receiver_is_weak : Warning <
+  "weak receiver may be unpredictably null in ARC mode">,
+  InGroup<DiagGroup<"receiver-is-weak">>, DefaultIgnore;
 
 def error_synthesized_ivar_yet_not_supported : Error<
   "instance variable synthesis not yet supported"
index 448f145964788ca7e6f5ec0f628574c5068daef1..b62d56efdab60ca78e3d24833e990aa94b67de2f 100644 (file)
@@ -2232,6 +2232,11 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
   }
 
   if (getLangOpts().ObjCAutoRefCount) {
+    if (Receiver &&
+        (Receiver->IgnoreParenImpCasts()->getType().getObjCLifetime() 
+          == Qualifiers::OCL_Weak))
+      Diag(Receiver->getLocStart(), diag::warn_receiver_is_weak);
+    
     // In ARC, annotate delegate init calls.
     if (Result->getMethodFamily() == OMF_init &&
         (SuperLoc.isValid() || isSelfExpr(Receiver))) {
diff --git a/test/SemaObjC/weak-receiver-warn.m b/test/SemaObjC/weak-receiver-warn.m
new file mode 100644 (file)
index 0000000..f3955da
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wreceiver-is-weak -verify %s
+// rdar://10225276
+
+@interface Test0
+- (void) setBlock: (void(^)(void)) block;
+- (void) addBlock: (void(^)(void)) block;
+- (void) actNow;
+@end
+
+void test0(Test0 *x) {
+  __weak Test0 *weakx = x;
+  [x addBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}}
+  [x setBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}}
+  x.block = ^{ [weakx actNow]; }; // expected-warning {{weak receiver may be unpredictably null in ARC mode}}
+
+  [weakx addBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}}
+  [weakx setBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}}
+  weakx.block = ^{ [x actNow]; };
+}