forked from OSchip/llvm-project
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>. llvm-svn: 170763
This commit is contained in:
parent
b420ef75fb
commit
b39cfd41f2
|
@ -1788,6 +1788,10 @@ def warn_attribute_weak_on_local : Warning<
|
|||
"__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<
|
||||
|
|
|
@ -6780,13 +6780,30 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
|
|||
// 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);
|
||||
|
|
|
@ -4,6 +4,21 @@ typedef unsigned long NSUInteger;
|
|||
typedef const void * CFTypeRef;
|
||||
CFTypeRef CFBridgingRetain(id X);
|
||||
id CFBridgingRelease(CFTypeRef);
|
||||
@protocol NSCopying @end
|
||||
@interface NSDictionary
|
||||
+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
|
||||
- (void)setObject:(id)object forKeyedSubscript:(id)key;
|
||||
@end
|
||||
@class NSFastEnumerationState;
|
||||
@protocol NSFastEnumeration
|
||||
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id [])buffer count:(NSUInteger)len;
|
||||
@end
|
||||
@interface NSNumber
|
||||
+ (NSNumber *)numberWithInt:(int)value;
|
||||
@end
|
||||
@interface NSArray <NSFastEnumeration>
|
||||
+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
|
||||
@end
|
||||
|
||||
void test0(void (*fn)(int), int val) {
|
||||
fn(val);
|
||||
|
@ -717,3 +732,12 @@ void _NSCalcBeze(NSColor* color, NSColor* bezelColors[]); // expected-error {{mu
|
|||
- 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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue