summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-06-08 22:46:07 +0000
committerJordan Rose <jordan_rose@apple.com>2012-06-08 22:46:07 +0000
commitd8d56694352c972bfb1e13bdc562b3d27b29f4ea (patch)
treeab85fc5b75273c7fde46690a4c5e61702926b540 /clang
parent9b4cbec703187c0bcff2d456d8979d7b1983499b (diff)
downloadbcm5719-llvm-d8d56694352c972bfb1e13bdc562b3d27b29f4ea.tar.gz
bcm5719-llvm-d8d56694352c972bfb1e13bdc562b3d27b29f4ea.zip
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
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--clang/lib/Sema/SemaDecl.cpp11
-rw-r--r--clang/test/SemaObjCXX/arc-0x.mm23
3 files changed, 37 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e50138dccf1..235c6abdaee 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1469,6 +1469,10 @@ def warn_cxx98_compat_unicode_type : Warning<
// Objective-C++
def err_objc_decls_may_only_appear_in_global_scope : Error<
"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
def err_nsobject_attribute : Error<
"__attribute ((NSObject)) is for pointer types only">;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 68f74694577..40cc35117c8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6303,6 +6303,17 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
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
// the previously declared type.
if (VarDecl *Old = VDecl->getPreviousDecl())
diff --git a/clang/test/SemaObjCXX/arc-0x.mm b/clang/test/SemaObjCXX/arc-0x.mm
index 28eec51775b..88b3ab11786 100644
--- a/clang/test/SemaObjCXX/arc-0x.mm
+++ b/clang/test/SemaObjCXX/arc-0x.mm
@@ -22,7 +22,7 @@ void deduction(id obj) {
__strong id *idp = new auto(obj);
__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;
}
@@ -51,3 +51,24 @@ void test1c() {
(void) ^{ (void) p; };
(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
+}
+
+
OpenPOWER on IntegriCloud