objc: deprecate direct usage of 'isa' of objc objects
in favor of usage of api's intended for.
// rdar://8290002


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148404 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 2593697..fcc9e94 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -511,6 +511,10 @@
 def warn_objc_property_no_assignment_attribute : Warning<
   "no 'assign', 'retain', or 'copy' attribute is specified - "
   "'assign' is assumed">;
+def warn_objc_isa_use : Warning<
+  "direct access to objective-c's isa is deprecated "
+  "in favor of object_setClass() and object_getClass()">,
+  InGroup<DiagGroup<"deprecated-objective-c-isa-usage">>;
 def warn_objc_property_default_assign_on_object : Warning<
   "default property attribute 'assign' not appropriate for non-gc object">;
 def warn_property_attr_mismatch : Warning<
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 82249df..6bff219 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -1114,10 +1114,12 @@
         goto fail;
       // There's an implicit 'isa' ivar on all objects.
       // But we only actually find it this way on objects of type 'id',
-      // apparently.
-      if (OTy->isObjCId() && Member->isStr("isa"))
+      // apparently.ghjg
+      if (OTy->isObjCId() && Member->isStr("isa")) {
+        Diag(MemberLoc, diag::warn_objc_isa_use);
         return Owned(new (Context) ObjCIsaExpr(BaseExpr.take(), IsArrow, MemberLoc,
                                                Context.getObjCClassType()));
+      }
 
       if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
         return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index 0fdab83..ab129c8 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -918,7 +918,7 @@
 
 void pr6302(id x, Class y) {
   // This previously crashed the analyzer (reported in PR 6302)
-  x->isa  = y;
+  x->isa  = y; // expected-warning {{direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()}}
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/test/SemaObjC/id-isa-ref.m b/test/SemaObjC/id-isa-ref.m
index dfc0a5b..c2debb0 100644
--- a/test/SemaObjC/id-isa-ref.m
+++ b/test/SemaObjC/id-isa-ref.m
@@ -16,8 +16,9 @@
  
   id x;
 
-  [(*x).isa self];
-  [x->isa self];
+  // rdar://8290002
+  [(*x).isa self]; // expected-warning {{direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()}}
+  [x->isa self]; // expected-warning {{direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()}}
   
   Whatever *y;
 
diff --git a/test/SemaObjCXX/instantiate-expr.mm b/test/SemaObjCXX/instantiate-expr.mm
index 08be5f7..75a5b7e 100644
--- a/test/SemaObjCXX/instantiate-expr.mm
+++ b/test/SemaObjCXX/instantiate-expr.mm
@@ -20,10 +20,11 @@
 void f(U value, V value2) {
   get_an_A(N)->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}}
   get_an_A(N).prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}}
-  T c = get_an_id(N)->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}}
+  T c = get_an_id(N)->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \
+                           // expected-warning 5 {{direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()}}
 }
 
-template void f<6, Class>(int, int);
+template void f<6, Class>(int, int); // expected-note{{in instantiation of}}
 template void f<7, Class>(int*, int); // expected-note{{in instantiation of}}
 template void f<8, Class>(int, double*); // expected-note{{in instantiation of}}
 template void f<9, int>(int, int); // expected-note{{in instantiation of}}
@@ -44,10 +45,11 @@
 // an isa.
 template<typename T, typename U>
 void f3(U ptr) {
-  T c = ptr->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}}
+  T c = ptr->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \
+                  // expected-warning 2 {{direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()}}
 }
 
-template void f3<Class>(id);
+template void f3<Class>(id); // expected-note{{in instantiation of}}
 template void f3<int>(id); // expected-note{{instantiation of}}
 
 // Implicit setter/getter