Skip to content

Commit 1c982af

Browse files
committed
[ObjC] Add some additional test cases around pointer conversions.
This is especially important for Objective-C++, which is entirely missing this testing at the moment. This annotates with "FIXME" the cases which I change in the next patch -- I primarily wanted to document the current state of things so that the effect of the code change is made clear. Differential Revision: https://reviews.llvm.org/D67982 llvm-svn: 375124
1 parent 92e498d commit 1c982af

File tree

7 files changed

+286
-31
lines changed

7 files changed

+286
-31
lines changed

clang/test/SemaObjC/class-method-self.m

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// RUN: %clang_cc1 -verify -Wno-objc-root-class %s
22

3-
typedef struct objc_class *Class;
43
@interface XX
54

65
- (void)addObserver:(XX*)o; // expected-note 2{{passing argument to parameter 'o' here}}
@@ -23,4 +22,3 @@ + (void)classMethod {
2322
[obj addObserver:whatever]; // expected-warning {{incompatible pointer types sending 'Class' to parameter of type 'XX *'}}
2423
}
2524
@end
26-

clang/test/SemaObjC/comptypes-1.m

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
22

33
#define nil (void *)0;
4-
#define Nil (void *)0;
54

65
extern void foo();
76

87
@protocol MyProtocol
98
- (void) foo;
9+
+ (void) bar;
1010
@end
1111

1212
@interface MyClass
@@ -22,20 +22,24 @@ int main()
2222
id<MyProtocol> obj_p = nil;
2323
MyClass *obj_c = nil;
2424
MyOtherClass *obj_cp = nil;
25-
Class obj_C = Nil;
25+
Class obj_C = nil;
26+
Class<MyProtocol> obj_CP = nil;
2627

2728
/* Assigning to an 'id' variable should never
2829
generate a warning. */
2930
obj = obj_p; /* Ok */
3031
obj = obj_c; /* Ok */
3132
obj = obj_cp; /* Ok */
3233
obj = obj_C; /* Ok */
33-
34+
obj = obj_CP; /* Ok */
35+
3436
/* Assigning to a 'MyClass *' variable should always generate a
3537
warning, unless done from an 'id'. */
3638
obj_c = obj; /* Ok */
37-
obj_c = obj_cp; // // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'MyOtherClass *'}}
39+
obj_c = obj_p; // expected-warning {{assigning to 'MyClass *' from incompatible type 'id<MyProtocol>'}}
40+
obj_c = obj_cp; // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'MyOtherClass *'}}
3841
obj_c = obj_C; // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'Class'}}
42+
obj_c = obj_CP; // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'Class<MyProtocol>'}}
3943

4044
/* Assigning to an 'id<MyProtocol>' variable should generate a
4145
warning if done from a 'MyClass *' (which doesn't implement
@@ -45,6 +49,7 @@ int main()
4549
obj_p = obj_c; // expected-warning {{assigning to 'id<MyProtocol>' from incompatible type 'MyClass *'}}
4650
obj_p = obj_cp; /* Ok */
4751
obj_p = obj_C; // expected-warning {{incompatible pointer types assigning to 'id<MyProtocol>' from 'Class'}}
52+
obj_p = obj_CP; // FIXME -- should warn {{assigning to 'id<MyProtocol>' from incompatible type 'Class<MyProtocol>'}}
4853

4954
/* Assigning to a 'MyOtherClass *' variable should always generate
5055
a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
@@ -53,37 +58,67 @@ int main()
5358
obj_cp = obj_c; // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'MyClass *'}}
5459
obj_cp = obj_p; /* Ok */
5560
obj_cp = obj_C; // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'Class'}}
61+
obj_cp = obj_CP; // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'Class<MyProtocol>'}}
62+
63+
obj_C = obj; // Ok
64+
obj_C = obj_p; // expected-warning {{incompatible pointer types assigning to 'Class' from 'id<MyProtocol>'}}
65+
obj_C = obj_c; // expected-warning {{incompatible pointer types assigning to 'Class' from 'MyClass *'}}
66+
obj_C = obj_cp; // expected-warning {{incompatible pointer types assigning to 'Class' from 'MyOtherClass *'}}
67+
obj_C = obj_CP; // Ok
68+
69+
obj_CP = obj; // Ok
70+
obj_CP = obj_p; // expected-warning {{assigning to 'Class<MyProtocol>' from incompatible type 'id<MyProtocol>'}}
71+
obj_CP = obj_c; // expected-warning {{incompatible pointer types assigning to 'Class<MyProtocol>' from 'MyClass *}}
72+
obj_CP = obj_cp; // expected-warning {{incompatible pointer types assigning to 'Class<MyProtocol>' from 'MyOtherClass *'}}
73+
obj_CP = obj_C; // Ok
5674

5775
/* Any comparison involving an 'id' must be without warnings. */
58-
if (obj == obj_p) foo() ; /* Ok */ /*Bogus warning here in 2.95.4*/
59-
if (obj_p == obj) foo() ; /* Ok */
60-
if (obj == obj_c) foo() ; /* Ok */
61-
if (obj_c == obj) foo() ; /* Ok */
62-
if (obj == obj_cp) foo() ; /* Ok */
63-
if (obj_cp == obj) foo() ; /* Ok */
64-
if (obj == obj_C) foo() ; /* Ok */
65-
if (obj_C == obj) foo() ; /* Ok */
76+
if (obj == obj_p) foo(); /* Ok */ /*Bogus warning here in 2.95.4*/
77+
if (obj_p == obj) foo(); /* Ok */
78+
if (obj == obj_c) foo(); /* Ok */
79+
if (obj_c == obj) foo(); /* Ok */
80+
if (obj == obj_cp) foo(); /* Ok */
81+
if (obj_cp == obj) foo(); /* Ok */
82+
if (obj == obj_C) foo(); /* Ok */
83+
if (obj_C == obj) foo(); /* Ok */
84+
if (obj == obj_CP) foo(); /* Ok */
85+
if (obj_CP == obj) foo(); /* Ok */
6686

6787
/* Any comparison between 'MyClass *' and anything which is not an 'id'
6888
must generate a warning. */
69-
if (obj_p == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'MyClass *')}}
89+
if (obj_c == obj_p) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'id<MyProtocol>')}}
90+
if (obj_p == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'MyClass *')}}
91+
92+
if (obj_c == obj_cp) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}}
93+
if (obj_cp == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}}
7094

71-
if (obj_c == obj_cp) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}}
72-
if (obj_cp == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}}
95+
if (obj_c == obj_C) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('MyClass *' and 'Class')}}
96+
if (obj_C == obj_c) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('Class' and 'MyClass *')}}
7397

74-
if (obj_c == obj_C) foo() ;
75-
if (obj_C == obj_c) foo() ;
98+
if (obj_c == obj_CP) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'Class<MyProtocol>')}}
99+
if (obj_CP == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('Class<MyProtocol>' and 'MyClass *')}}
76100

77101
/* Any comparison between 'MyOtherClass *' (which implements
78102
MyProtocol) and an 'id' implementing MyProtocol are Ok. */
79-
if (obj_cp == obj_p) foo() ; /* Ok */
80-
if (obj_p == obj_cp) foo() ; /* Ok */
103+
if (obj_p == obj_cp) foo(); /* Ok */
104+
if (obj_cp == obj_p) foo(); /* Ok */
105+
106+
if (obj_p == obj_C) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('id<MyProtocol>' and 'Class')}}
107+
if (obj_C == obj_p) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('Class' and 'id<MyProtocol>')}}
108+
109+
if (obj_p == obj_CP) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('id<MyProtocol>' and 'Class<MyProtocol>')}}
110+
if (obj_CP == obj_p) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('Class<MyProtocol>' and 'id<MyProtocol>')}}
111+
112+
/* Comparisons between MyOtherClass * and Class types is a warning */
113+
if (obj_cp == obj_C) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('MyOtherClass *' and 'Class')}}
114+
if (obj_C == obj_cp) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('Class' and 'MyOtherClass *')}}
81115

116+
if (obj_cp == obj_CP) foo(); // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'Class<MyProtocol>')}}
117+
if (obj_CP == obj_cp) foo(); // expected-warning {{comparison of distinct pointer types ('Class<MyProtocol>' and 'MyOtherClass *')}}
82118

83-
if (obj_p == obj_C) foo() ;
84-
if (obj_C == obj_p) foo() ;
85-
if (obj_cp == obj_C) foo() ;
86-
if (obj_C == obj_cp) foo() ;
119+
/* Comparisons between a Class and a Class<MyProtocol> are ok */
120+
if (obj_C == obj_CP) foo(); /* Ok */
121+
if (obj_CP == obj_C) foo(); /* Ok */
87122

88123
return 0;
89124
}

clang/test/SemaObjC/comptypes-7.m

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
22

33
#define nil (void *)0;
4-
#define Nil (void *)0;
54

65
extern void foo();
76

@@ -17,7 +16,7 @@ int main()
1716
id obj = nil;
1817
id <MyProtocol> obj_p = nil;
1918
MyClass *obj_c = nil;
20-
Class obj_C = Nil;
19+
Class obj_C = nil;
2120

2221
int i = 0;
2322
int *j = nil;
@@ -66,8 +65,8 @@ int main()
6665
if (obj_C == j) foo() ; // expected-warning {{comparison of distinct pointer types ('Class' and 'int *')}}
6766
if (j == obj_C) foo() ; // expected-warning {{comparison of distinct pointer types ('int *' and 'Class')}}
6867

69-
Class bar1 = Nil;
70-
Class <MyProtocol> bar = Nil;
68+
Class bar1 = nil;
69+
Class <MyProtocol> bar = nil;
7170
bar = bar1;
7271
bar1 = bar;
7372

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_cc1 -verify -Wno-objc-root-class %s
2+
// FIXME: expected-no-diagnostics
3+
@interface XX
4+
5+
- (void)addObserver:(XX*)o; // FIXME -- should note 2{{passing argument to parameter 'o' here}}
6+
7+
@end
8+
9+
@interface YY
10+
11+
+ (void)classMethod;
12+
13+
@end
14+
15+
@implementation YY
16+
17+
static XX *obj;
18+
19+
+ (void)classMethod {
20+
[obj addObserver:self]; // FIXME -- should error {{cannot initialize a parameter of type 'XX *' with an lvalue of type 'Class'}}
21+
Class whatever;
22+
[obj addObserver:whatever]; // FIXME -- should error {{cannot initialize a parameter of type 'XX *' with an lvalue of type 'Class'}}
23+
}
24+
@end
25+

clang/test/SemaObjCXX/comptypes-1.mm

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
2+
3+
#define nil nullptr
4+
5+
extern void foo();
6+
7+
@protocol MyProtocol
8+
- (void) foo;
9+
+ (void) bar;
10+
@end
11+
12+
@interface MyClass
13+
@end
14+
15+
@interface MyOtherClass <MyProtocol>
16+
- (void) foo;
17+
@end
18+
19+
int main()
20+
{
21+
id obj = nil;
22+
id<MyProtocol> obj_p = nil;
23+
MyClass *obj_c = nil;
24+
MyOtherClass *obj_cp = nil;
25+
Class obj_C = nil;
26+
Class<MyProtocol> obj_CP = nil;
27+
28+
/* Assigning to an 'id' variable should never
29+
generate a warning. */
30+
obj = obj_p; /* Ok */
31+
obj = obj_c; /* Ok */
32+
obj = obj_cp; /* Ok */
33+
obj = obj_C; /* Ok */
34+
obj = obj_CP; /* Ok */
35+
36+
/* Assigning to a 'MyClass *' variable should always generate a
37+
warning, unless done from an 'id'. */
38+
obj_c = obj; /* Ok */
39+
obj_c = obj_p; // expected-error {{assigning to 'MyClass *' from incompatible type 'id<MyProtocol>'}}
40+
obj_c = obj_cp; // expected-error {{assigning to 'MyClass *' from incompatible type 'MyOtherClass *'}}
41+
obj_c = obj_C; // FIXME -- should error {{assigning to 'MyClass *' from incompatible type 'Class'}}
42+
obj_c = obj_CP; // expected-error {{assigning to 'MyClass *' from incompatible type 'Class<MyProtocol>'}}
43+
44+
/* Assigning to an 'id<MyProtocol>' variable should generate a
45+
warning if done from a 'MyClass *' (which doesn't implement
46+
MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
47+
(which implements MyProtocol). */
48+
obj_p = obj; /* Ok */
49+
obj_p = obj_c; // expected-error {{assigning to 'id<MyProtocol>' from incompatible type 'MyClass *'}}
50+
obj_p = obj_cp; /* Ok */
51+
obj_p = obj_C; // FIXME -- should error {{assigning to 'id<MyProtocol>' from incompatible type 'Class'}}
52+
obj_p = obj_CP; // FIXME -- should error {{assigning to 'id<MyProtocol>' from incompatible type 'Class<MyProtocol>'}}
53+
54+
/* Assigning to a 'MyOtherClass *' variable should always generate
55+
a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
56+
MyOtherClass implements MyProtocol). */
57+
obj_cp = obj; /* Ok */
58+
obj_cp = obj_c; // expected-error {{assigning to 'MyOtherClass *' from incompatible type 'MyClass *'}}
59+
obj_cp = obj_p; /* Ok */
60+
obj_cp = obj_C; // FIXME -- should error {{assigning to 'MyOtherClass *' from incompatible type 'Class'}}
61+
obj_cp = obj_CP; // expected-error {{assigning to 'MyOtherClass *' from incompatible type 'Class<MyProtocol>'}}
62+
63+
obj_C = obj; // Ok
64+
obj_C = obj_p; // FIXME -- should error {{assigning to 'Class' from incompatible type 'id<MyProtocol>'}}
65+
obj_C = obj_c; // FIXME -- should error {{assigning to 'Class' from incompatible type 'MyClass *'}}
66+
obj_C = obj_cp; // FIXME -- should error {{assigning to 'Class' from incompatible type 'MyOtherClass *'}}
67+
obj_C = obj_CP; // Ok
68+
69+
obj_CP = obj; // Ok
70+
obj_CP = obj_p; // expected-warning {{incompatible pointer types assigning to 'Class<MyProtocol>' from 'id<MyProtocol>'}} FIXME -- should error {{assigning to 'Class<MyProtocol>' from incompatible type 'id<MyProtocol>'}}
71+
obj_CP = obj_c; // expected-error {{assigning to 'Class<MyProtocol>' from incompatible type 'MyClass *}}
72+
obj_CP = obj_cp; // expected-error {{assigning to 'Class<MyProtocol>' from incompatible type 'MyOtherClass *'}}
73+
obj_CP = obj_C; // Ok
74+
75+
/* Any comparison involving an 'id' must be without warnings. */
76+
if (obj == obj_p) foo(); /* Ok */ /*Bogus warning here in 2.95.4*/
77+
if (obj_p == obj) foo(); /* Ok */
78+
if (obj == obj_c) foo(); /* Ok */
79+
if (obj_c == obj) foo(); /* Ok */
80+
if (obj == obj_cp) foo(); /* Ok */
81+
if (obj_cp == obj) foo(); /* Ok */
82+
if (obj == obj_C) foo(); /* Ok */
83+
if (obj_C == obj) foo(); /* Ok */
84+
if (obj == obj_CP) foo(); /* Ok */
85+
if (obj_CP == obj) foo(); /* Ok */
86+
87+
/* Any comparison between 'MyClass *' and anything which is not an 'id'
88+
must generate a warning. */
89+
if (obj_c == obj_p) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'id<MyProtocol>')}}
90+
if (obj_p == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'MyClass *')}}
91+
92+
if (obj_c == obj_cp) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}}
93+
if (obj_cp == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}}
94+
95+
if (obj_c == obj_C) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('MyClass *' and 'Class')}}
96+
if (obj_C == obj_c) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('Class' and 'MyClass *')}}
97+
98+
if (obj_c == obj_CP) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'Class<MyProtocol>')}}
99+
if (obj_CP == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('Class<MyProtocol>' and 'MyClass *')}}
100+
101+
/* Any comparison between 'MyOtherClass *' (which implements
102+
MyProtocol) and an 'id' implementing MyProtocol are Ok. */
103+
if (obj_p == obj_cp) foo(); /* Ok */
104+
if (obj_cp == obj_p) foo(); /* Ok */
105+
106+
if (obj_p == obj_C) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('id<MyProtocol>' and 'Class')}}
107+
if (obj_C == obj_p) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('Class' and 'id<MyProtocol>')}}
108+
109+
if (obj_p == obj_CP) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('id<MyProtocol>' and 'Class<MyProtocol>')}}
110+
if (obj_CP == obj_p) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('Class<MyProtocol>' and 'id<MyProtocol>')}}
111+
112+
/* Comparisons between MyOtherClass * and Class types is a warning */
113+
if (obj_cp == obj_C) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('MyOtherClass *' and 'Class')}}
114+
if (obj_C == obj_cp) foo(); // FIXME -- should warn {{comparison of distinct pointer types ('Class' and 'MyOtherClass *')}}
115+
116+
if (obj_cp == obj_CP) foo(); // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'Class<MyProtocol>')}}
117+
if (obj_CP == obj_cp) foo(); // expected-warning {{comparison of distinct pointer types ('Class<MyProtocol>' and 'MyOtherClass *')}}
118+
119+
/* Comparisons between a Class and a Class<MyProtocol> are ok */
120+
if (obj_C == obj_CP) foo(); /* Ok */
121+
if (obj_CP == obj_C) foo(); /* Ok */
122+
123+
return 0;
124+
}

0 commit comments

Comments
 (0)