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
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 68f7469..40cc351 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6303,6 +6303,17 @@
     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())