1 | // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s |
2 | |
3 | void takevoidptr(void*); |
4 | |
5 | |
6 | @interface Foo |
7 | - iMethod; |
8 | + cMethod; |
9 | @end |
10 | |
11 | @interface A |
12 | + superClassMethod; |
13 | - (void)instanceMethod; |
14 | @end |
15 | |
16 | @interface B : A |
17 | - (void)instanceMethod; |
18 | + classMethod; |
19 | @end |
20 | |
21 | @implementation B |
22 | |
23 | - (void)instanceMethod { |
24 | [super iMethod]; // expected-warning{{'A' may not respond to 'iMethod'}} |
25 | |
26 | // Use of super in a block is ok and does codegen to the right thing. |
27 | // rdar://7852959 |
28 | takevoidptr(^{ |
29 | [super instanceMethod]; |
30 | }); |
31 | } |
32 | |
33 | + classMethod { |
34 | [super cMethod]; // expected-warning{{method '+cMethod' not found (return type defaults to 'id')}} |
35 | |
36 | id X[] = { [ super superClassMethod] }; |
37 | id Y[] = { |
38 | [ super.superClassMethod iMethod], |
39 | super.superClassMethod, |
40 | (id)super.superClassMethod // not a cast of super: rdar://7853261 |
41 | }; |
42 | return 0; |
43 | } |
44 | @end |
45 | |
46 | @interface XX |
47 | - m; |
48 | @end |
49 | |
50 | void f(id super) { |
51 | [super m]; |
52 | } |
53 | void f0(int super) { |
54 | [super m]; // expected-warning{{receiver type 'int' is not 'id'}} |
55 | } |
56 | void f1(id puper) { // expected-note {{'puper' declared here}} |
57 | [super m]; // expected-error{{use of undeclared identifier 'super'}} |
58 | } |
59 | |
60 | // radar 7400691 |
61 | typedef Foo super; |
62 | |
63 | typedef Foo FooTD; |
64 | |
65 | void test() { |
66 | [FooTD cMethod]; |
67 | [super cMethod]; |
68 | } |
69 | |
70 | struct SomeStruct { |
71 | int X; |
72 | }; |
73 | |
74 | int test2() { |
75 | struct SomeStruct super = { 0 }; |
76 | return super.X; |
77 | } |
78 | |
79 | int test3() { |
80 | id super = 0; |
81 | [(B*)super instanceMethod]; |
82 | int *s1 = (int*)super; |
83 | |
84 | id X[] = { [ super superClassMethod] }; |
85 | return 0; |
86 | } |
87 | |