[cfe-commits] r170763 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaObjC/arc.m

Ted Kremenek kremenek at apple.com
Thu Dec 20 12:55:03 PST 2012


Author: kremenek
Date: Thu Dec 20 14:55:03 2012
New Revision: 170763

URL: http://llvm.org/viewvc/llvm-project?rev=170763&view=rev
Log:
Warn if a __weak variable is initialized with an Objective-C object literal.

Such variables may immediately become nil or may have unpredictable
behavior.

Fixes <rdar://problem/12569201>.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaObjC/arc.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=170763&r1=170762&r2=170763&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Dec 20 14:55:03 2012
@@ -1788,6 +1788,10 @@
   "__weak attribute cannot be specified on an automatic variable when ARC "
   "is not enabled">,
   InGroup<IgnoredAttributes>;
+def warn_attribute_weak_objc_literal : Warning<
+  "__weak variable initialized with an object literal may "
+  "immediately become nil">,
+  InGroup<DiagGroup<"objc-weak-assigned-literal">>;
 def warn_weak_identifier_undeclared : Warning<
   "weak identifier %0 never declared">;
 def err_attribute_weak_static : Error<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=170763&r1=170762&r2=170763&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Dec 20 14:55:03 2012
@@ -6780,13 +6780,30 @@
     // we do not warn to warn spuriously when 'x' and 'y' are on separate
     // paths through the function. This should be revisited if
     // -Wrepeated-use-of-weak is made flow-sensitive.
-    if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong) {
+    Qualifiers::ObjCLifetime Lifetime = VDecl->getType().getObjCLifetime();
+    if (Lifetime == Qualifiers::OCL_Strong) {
       DiagnosticsEngine::Level Level =
         Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
                                  Init->getLocStart());
       if (Level != DiagnosticsEngine::Ignored)
         getCurFunction()->markSafeWeakUse(Init);
     }
+    else if (Lifetime == Qualifiers::OCL_Weak) {
+      // Check if we are initializing a __weak variable with an Objective-C
+      // object literal.  Since there is no other strong reference, the
+      // __weak variable may immediately become nil.
+      Expr *InitSansParen = Init->IgnoreParenImpCasts();
+      switch (InitSansParen->getStmtClass()) {
+        default: break;
+        case Stmt::BlockExprClass:
+        case Stmt::ObjCArrayLiteralClass:
+        case Stmt::ObjCDictionaryLiteralClass:
+        case Stmt::ObjCStringLiteralClass:
+          Diag(VDecl->getLocation(), diag::warn_attribute_weak_objc_literal)
+            << Init->getSourceRange();
+          break;
+      }
+    }
   }
 
   Init = MaybeCreateExprWithCleanups(Init);

Modified: cfe/trunk/test/SemaObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc.m?rev=170763&r1=170762&r2=170763&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc.m (original)
+++ cfe/trunk/test/SemaObjC/arc.m Thu Dec 20 14:55:03 2012
@@ -4,6 +4,21 @@
 typedef const void * CFTypeRef;
 CFTypeRef CFBridgingRetain(id X);
 id CFBridgingRelease(CFTypeRef);
+ at protocol NSCopying @end
+ at interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+ at end
+ at class NSFastEnumerationState;
+ at protocol NSFastEnumeration
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id [])buffer count:(NSUInteger)len;
+ at end
+ at interface NSNumber 
++ (NSNumber *)numberWithInt:(int)value;
+ at end
+ at interface NSArray <NSFastEnumeration>
++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
+ at end
 
 void test0(void (*fn)(int), int val) {
   fn(val);
@@ -717,3 +732,12 @@
 - init { return 0; }
 @end
 
+// <rdar://problem/12569201>.  Warn on cases of initializing a weak variable
+// with an Objective-C object literal.
+void rdar12569201(id key, id value) {
+    __weak id x = @"foo"; // expected-warning {{__weak variable initialized with an object literal may immediately become nil}}
+    __weak id y = @{ key : value }; // expected-warning {{__weak variable initialized with an object literal may immediately become nil}}
+    __weak id z = @[ value ]; // expected-warning {{__weak variable initialized with an object literal may immediately become nil}}
+    __weak id b = ^() {}; // expected-warning {{__weak variable initialized with an object literal may immediately become nil}}
+    __weak __block id b2 = ^() {}; // expected-warning {{__weak variable initialized with an object literal may immediately become nil}}
+}





More information about the cfe-commits mailing list