forked from OSchip/llvm-project
Warn in ObjC++ when an 'auto' variable deduces type 'id'.
This could happen for cases like this: - (NSArray *)getAllNames:(NSArray *)images { NSMutableArray *results = [NSMutableArray array]; for (auto img in images) { [results addObject:img.name]; } return results; } Here the property access will fail because 'img' has type 'id', rather than, say, NSImage. This warning will not fire in templated code, since the 'id' could have come from a template parameter. llvm-svn: 158239
This commit is contained in:
parent
9b4cbec703
commit
d8d5669435
|
@ -1469,6 +1469,10 @@ def warn_cxx98_compat_unicode_type : Warning<
|
||||||
// Objective-C++
|
// Objective-C++
|
||||||
def err_objc_decls_may_only_appear_in_global_scope : Error<
|
def err_objc_decls_may_only_appear_in_global_scope : Error<
|
||||||
"Objective-C declarations may only appear in global scope">;
|
"Objective-C declarations may only appear in global scope">;
|
||||||
|
def warn_auto_var_is_id : Warning<
|
||||||
|
"'auto' deduced as 'id' in declaration of %0">,
|
||||||
|
InGroup<DiagGroup<"auto-var-id">>;
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
def err_nsobject_attribute : Error<
|
def err_nsobject_attribute : Error<
|
||||||
"__attribute ((NSObject)) is for pointer types only">;
|
"__attribute ((NSObject)) is for pointer types only">;
|
||||||
|
|
|
@ -6303,6 +6303,17 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
|
||||||
if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
|
if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
|
||||||
VDecl->setInvalidDecl();
|
VDecl->setInvalidDecl();
|
||||||
|
|
||||||
|
// Warn if we deduced 'id'. 'auto' usually implies type-safety, but using
|
||||||
|
// 'id' instead of a specific object type prevents most of our usual checks.
|
||||||
|
// We only want to warn outside of template instantiations, though:
|
||||||
|
// inside a template, the 'id' could have come from a parameter.
|
||||||
|
if (ActiveTemplateInstantiations.empty() &&
|
||||||
|
DeducedType->getType()->isObjCIdType()) {
|
||||||
|
SourceLocation Loc = DeducedType->getTypeLoc().getBeginLoc();
|
||||||
|
Diag(Loc, diag::warn_auto_var_is_id)
|
||||||
|
<< VDecl->getDeclName() << DeduceInit->getSourceRange();
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a redeclaration, check that the type we just deduced matches
|
// If this is a redeclaration, check that the type we just deduced matches
|
||||||
// the previously declared type.
|
// the previously declared type.
|
||||||
if (VarDecl *Old = VDecl->getPreviousDecl())
|
if (VarDecl *Old = VDecl->getPreviousDecl())
|
||||||
|
|
|
@ -22,7 +22,7 @@ void deduction(id obj) {
|
||||||
__strong id *idp = new auto(obj);
|
__strong id *idp = new auto(obj);
|
||||||
|
|
||||||
__strong id array[17];
|
__strong id array[17];
|
||||||
for (auto x : array) {
|
for (auto x : array) { // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}}
|
||||||
__strong id *xPtr = &x;
|
__strong id *xPtr = &x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,3 +51,24 @@ void test1c() {
|
||||||
(void) ^{ (void) p; };
|
(void) ^{ (void) p; };
|
||||||
(void) ^{ (void) v; }; // expected-error {{cannot capture __autoreleasing variable in a block}}
|
(void) ^{ (void) v; }; // expected-error {{cannot capture __autoreleasing variable in a block}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// <rdar://problem/11319689>
|
||||||
|
// warn when initializing an 'auto' variable with an 'id' initializer expression
|
||||||
|
|
||||||
|
void testAutoId(id obj) {
|
||||||
|
auto x = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'x'}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...but don't warn if it's coming from a template parameter.
|
||||||
|
template<typename T>
|
||||||
|
void autoTemplateFunction(T param, id obj) {
|
||||||
|
auto x = param; // no-warning
|
||||||
|
auto y = obj; // expected-warning{{'auto' deduced as 'id' in declaration of 'y'}}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testAutoIdTemplate(id obj) {
|
||||||
|
autoTemplateFunction(obj, obj); // no-warning
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue