diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-03-19 18:06:10 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-03-19 18:06:10 +0000 |
commit | d4c60909ae7ad1ab603feedf04d457d72e85fbc4 (patch) | |
tree | c956c9eb71af6f7d411d749cef071683968e40a5 | |
parent | b9e1b75772db2c7db566c6034ba90a07f22e35eb (diff) |
Diagnose conversion of 'Class' to/from objective-c
object pointer types.
Fixes radar 7634850.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98970 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 12 | ||||
-rw-r--r-- | test/SemaObjC/class-method-self.m | 4 | ||||
-rw-r--r-- | test/SemaObjC/comptypes-1.m | 6 | ||||
-rw-r--r-- | test/SemaObjC/id.m | 3 | ||||
-rw-r--r-- | test/SemaObjC/warn-incompatible-builtin-types.m | 42 |
5 files changed, 60 insertions, 7 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 6bf8ab90de..28f921daca 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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 = diff --git a/test/SemaObjC/class-method-self.m b/test/SemaObjC/class-method-self.m index 71509baf90..6f7d1fd93f 100644 --- a/test/SemaObjC/class-method-self.m +++ b/test/SemaObjC/class-method-self.m @@ -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 diff --git a/test/SemaObjC/comptypes-1.m b/test/SemaObjC/comptypes-1.m index 24f704113d..5b1891d4af 100644 --- a/test/SemaObjC/comptypes-1.m +++ b/test/SemaObjC/comptypes-1.m @@ -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*/ diff --git a/test/SemaObjC/id.m b/test/SemaObjC/id.m index 98904fe1ee..206127a5cc 100644 --- a/test/SemaObjC/id.m +++ b/test/SemaObjC/id.m @@ -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 index 0000000000..2a5005a396 --- /dev/null +++ b/test/SemaObjC/warn-incompatible-builtin-types.m @@ -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'}} +} |