if (PerformImplicitConversion(rExpr, lhsType.getUnqualifiedType(),
"assigning"))
return Incompatible;
- else
- return Compatible;
+ return Compatible;
}
// FIXME: Currently, we fall through and treat C++ classes like C
// 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;
}
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
// 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;
+