]> granicus.if.org Git - clang/commitdiff
Diagnose conversion of 'Class' to/from objective-c
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 19 Mar 2010 18:06:10 +0000 (18:06 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 19 Mar 2010 18:06:10 +0000 (18:06 +0000)
object pointer types.
Fixes radar 7634850.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98970 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaObjC/class-method-self.m
test/SemaObjC/comptypes-1.m
test/SemaObjC/id.m
test/SemaObjC/warn-incompatible-builtin-types.m [new file with mode: 0644]

index 6bf8ab90de487261bbb4cbf2d824b4dcfae236fc..28f921dacaf04021436504797b88768694dd404d 100644 (file)
@@ -4592,8 +4592,18 @@ Sema::CheckBlockPointerTypesForAssignment(QualType lhsType,
 /// for assignment compatibility.
 Sema::AssignConvertType
 Sema::CheckObjCPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
-  if (lhsType->isObjCBuiltinType() || rhsType->isObjCBuiltinType())
+  if (lhsType->isObjCBuiltinType()) {
+    // Class is not compatible with ObjC object pointers.
+    if (lhsType->isObjCClassType() && !rhsType->isObjCBuiltinType())
+      return IncompatiblePointer;
     return Compatible;
+  }
+  if (rhsType->isObjCBuiltinType()) {
+    // Class is not compatible with ObjC object pointers.
+    if (rhsType->isObjCClassType() && !lhsType->isObjCBuiltinType())
+      return IncompatiblePointer;
+    return Compatible;
+  }
   QualType lhptee =
   lhsType->getAs<ObjCObjectPointerType>()->getPointeeType();
   QualType rhptee =
index 71509baf9012e253ed0f9fb0640c7dbe32695b43..6f7d1fd93f4fc106d2c5a0986311a287214e750f 100644 (file)
@@ -18,9 +18,9 @@ typedef struct objc_class *Class;
 static XX *obj;
 
 + (void)classMethod {
-  [obj addObserver:self];
+  [obj addObserver:self];     // expected-warning {{incompatible pointer types sending 'Class', expected 'XX *'}}
   Class whatever;
-  [obj addObserver:whatever]; // GCC warns about this.
+  [obj addObserver:whatever]; // expected-warning {{incompatible pointer types sending 'Class', expected 'XX *'}} 
 }
 @end
 
index 24f704113d7c8ac4892c0b5e93c56f16af18c9d7..5b1891d4af2e73441a00482e269b2b4458512de6 100644 (file)
@@ -35,7 +35,7 @@ int main()
      warning, unless done from an 'id'.  */
   obj_c = obj;    /* Ok */
   obj_c = obj_cp; // // expected-warning {{incompatible pointer types assigning 'MyOtherClass *', expected 'MyClass *'}}
-  obj_c = obj_C;
+  obj_c = obj_C;  // expected-warning {{incompatible pointer types assigning 'Class', expected 'MyClass *'}}
 
   /* Assigning to an 'id<MyProtocol>' variable should generate a
      warning if done from a 'MyClass *' (which doesn't implement
@@ -44,7 +44,7 @@ int main()
   obj_p = obj;    /* Ok */
   obj_p = obj_c;  // expected-warning {{incompatible type assigning 'MyClass *', expected 'id<MyProtocol>'}}
   obj_p = obj_cp; /* Ok  */
-  obj_p = obj_C;  // Ok
+  obj_p = obj_C;  // expected-warning {{incompatible pointer types assigning 'Class', expected 'id<MyProtocol>'}}
 
   /* Assigning to a 'MyOtherClass *' variable should always generate
      a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
@@ -52,7 +52,7 @@ int main()
   obj_cp = obj;    /* Ok */
   obj_cp = obj_c;  // expected-warning {{incompatible pointer types assigning 'MyClass *', expected 'MyOtherClass *'}}
   obj_cp = obj_p;  /* Ok */
-  obj_cp = obj_C;
+  obj_cp = obj_C;  // expected-warning {{incompatible pointer types assigning 'Class', expected 'MyOtherClass *'}}
 
   /* Any comparison involving an 'id' must be without warnings.  */
   if (obj == obj_p) foo() ;  /* Ok  */ /*Bogus warning here in 2.95.4*/
index 98904fe1ee9cc8a0da83cfc1f0a0977aec93109f..206127a5ccef76aa2adf3785cc5ac2c6508da38b 100644 (file)
@@ -9,7 +9,8 @@ void foo() {
   // Test assignment compatibility of Class and id.  No warning should be
   // produced.
   // rdar://6770142 - Class and id<foo> are compatible.
-  S = T; T = S;
+  S = T; // expected-warning {{incompatible pointer types assigning 'Class', expected 'id<Foo>'}}
+  T = S; // expected-warning {{incompatible pointer types assigning 'id<Foo>', expected 'Class'}}
   R = T; T = R;
   R = S; S = R;
 }
diff --git a/test/SemaObjC/warn-incompatible-builtin-types.m b/test/SemaObjC/warn-incompatible-builtin-types.m
new file mode 100644 (file)
index 0000000..2a5005a
--- /dev/null
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar 7634850
+
+@interface Foo
+- (void)foo:(Class)class;
+@end
+
+void FUNC() {
+    Class c, c1;
+    SEL s1, s2;
+    id i, i1;
+    Foo *f;
+    [f foo:f]; // expected-warning {{incompatible pointer types sending 'Foo *', expected 'Class'}}
+    c = f;     // expected-warning {{incompatible pointer types assigning 'Foo *', expected 'Class'}}
+
+    c = i;
+
+    i = c;
+
+    c = c1;
+
+    i = i1;
+
+    s1 = i;    // expected-warning {{incompatible pointer types assigning 'id', expected 'SEL'}}
+    i = s1;    // expected-warning {{incompatible pointer types assigning 'SEL', expected 'id'}}
+
+    s1 = s2;
+
+    s1 = c;    // expected-warning {{incompatible pointer types assigning 'Class', expected 'SEL'}}
+
+    c = s1;    // expected-warning {{incompatible pointer types assigning 'SEL', expected 'Class'}}
+
+    f = i;
+
+    f = c;     // expected-warning {{incompatible pointer types assigning 'Class', expected 'Foo *'}}
+
+    f = s1;    // expected-warning {{incompatible pointer types assigning 'SEL', expected 'Foo *'}}
+
+    i = f;
+
+    s1 = f;    // expected-warning {{incompatible pointer types assigning 'Foo *', expected 'SEL'}}
+}