From: Chris Lattner Date: Sun, 12 Apr 2009 09:02:39 +0000 (+0000) Subject: Fix rdar://6770142 - Class and qualified id's are compatible, just like X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2c4463f744487e242f7c88b6daa0abf5cb24219e;p=clang Fix rdar://6770142 - Class and qualified id's are compatible, just like Class and unqualified id's are. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68899 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index e380f78ad0..0dc3b87d52 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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 diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 8d8fae035a..0c1f144802 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -681,11 +681,15 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, // Allow id 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; } diff --git a/test/SemaObjC/comptypes-1.m b/test/SemaObjC/comptypes-1.m index 4bca895ecb..aafd442fff 100644 --- a/test/SemaObjC/comptypes-1.m +++ b/test/SemaObjC/comptypes-1.m @@ -44,7 +44,7 @@ int main() obj_p = obj; /* Ok */ obj_p = obj_c; // expected-warning {{incompatible type assigning 'MyClass *', expected 'id'}} obj_p = obj_cp; /* Ok */ - obj_p = obj_C; // expected-warning {{incompatible type assigning 'Class', expected 'id'}} + obj_p = obj_C; // Ok /* Assigning to a 'MyOtherClass *' variable should always generate a warning, unless done from an 'id' or an 'id' (since diff --git a/test/SemaObjC/id-1.m b/test/SemaObjC/id-1.m index 399c6ec22c..1781ce71d9 100644 --- a/test/SemaObjC/id-1.m +++ b/test/SemaObjC/id-1.m @@ -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 S; +id R; +void foo() { + // Test assignment compatibility of Class and id. No warning should be + // produced. + // rdar://6770142 - Class and id 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; +