]> granicus.if.org Git - clang/commitdiff
Fix rdar://6770142 - Class and qualified id's are compatible, just like
authorChris Lattner <sabre@nondot.org>
Sun, 12 Apr 2009 09:02:39 +0000 (09:02 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 12 Apr 2009 09:02:39 +0000 (09:02 +0000)
Class and unqualified id's are.

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

lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprObjC.cpp
test/SemaObjC/comptypes-1.m
test/SemaObjC/id-1.m

index e380f78ad056f2f8177e257d6c06e1663277a0db..0dc3b87d524274680e3be2f26c5b1faa85d5c526 100644 (file)
@@ -3060,8 +3060,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
       if (PerformImplicitConversion(rExpr, lhsType.getUnqualifiedType(),
                                     "assigning"))
         return Incompatible;
-      else
-        return Compatible;
+      return Compatible;
     }
 
     // FIXME: Currently, we fall through and treat C++ classes like C
index 8d8fae035a1e57d26ec64200238fbc9a26d68565..0c1f1448028b7b2f18d7b813aa4a21daad83b8ee 100644 (file)
@@ -681,11 +681,15 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
   // Allow id<P..> and an 'id' or void* type in all cases.
   if (const PointerType *PT = lhs->getAsPointerType()) {
     QualType PointeeTy = PT->getPointeeType();
-    if (Context.isObjCIdStructType(PointeeTy) || PointeeTy->isVoidType())
+    if (PointeeTy->isVoidType() ||
+        Context.isObjCIdStructType(PointeeTy) || 
+        Context.isObjCClassStructType(PointeeTy))
       return true;
   } else if (const PointerType *PT = rhs->getAsPointerType()) {
     QualType PointeeTy = PT->getPointeeType();
-    if (Context.isObjCIdStructType(PointeeTy) || PointeeTy->isVoidType())
+    if (PointeeTy->isVoidType() ||
+        Context.isObjCIdStructType(PointeeTy) || 
+        Context.isObjCClassStructType(PointeeTy))
       return true;
   }
   
index 4bca895ecb3dcb457290e3b437964ef004f24787..aafd442fffe40062e79c91e1a5b25791cac293d4 100644 (file)
@@ -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;  // expected-warning {{incompatible type assigning 'Class', expected 'id<MyProtocol>'}}
+  obj_p = obj_C;  // Ok
 
   /* Assigning to a 'MyOtherClass *' variable should always generate
      a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
index 399c6ec22c6029112c53f731cd8be1f058289249..1781ce71d9c3385115d00e1646804e8879529f10 100644 (file)
@@ -1,6 +1,20 @@
 // RUN: clang-cc -fsyntax-only -verify %s
-/* Test attempt to redefine 'id' in an incompatible fashion.  */
 
-typedef int id;   // expected-error {{typedef redefinition with different types}}
+@protocol Foo;
+
+Class T;
+id<Foo> S;
+id R;
+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;
+  R = T; T = R;
+  R = S; S = R;
+}
 
+// Test attempt to redefine 'id' in an incompatible fashion.
+typedef int id;   // expected-error {{typedef redefinition with different types}}
 id b;
+