1 | // RUN: rm -rf %t |
2 | // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -Wreturn-type -fmodules-cache-path=%t -I %S/Inputs %s -verify -Wno-objc-root-class |
3 | |
4 | @class C2; |
5 | @class C3; |
6 | @class C3; |
7 | @import redecl_merge_left; |
8 | typedef struct my_struct_type *my_struct_ref; |
9 | @protocol P4; |
10 | @class C3; |
11 | @class C3; |
12 | |
13 | int *call_eventually_noreturn(void) { |
14 | eventually_noreturn(); |
15 | } // expected-warning{{control reaches end of non-void function}} |
16 | |
17 | int *call_eventually_noreturn2(void) { |
18 | eventually_noreturn2(); |
19 | } // expected-warning{{control reaches end of non-void function}} |
20 | |
21 | @import redecl_merge_right; |
22 | |
23 | int *call_eventually_noreturn_again(void) { |
24 | eventually_noreturn(); |
25 | } |
26 | |
27 | int *call_eventually_noreturn2_again(void) { |
28 | // noreturn and non-noreturn functions have different types |
29 | eventually_noreturn2(); // expected-error{{call to 'eventually_noreturn2' is ambiguous}} |
30 | // expected-note@Inputs/redecl-merge-left.h:93{{candidate function}} |
31 | // expected-note@Inputs/redecl-merge-right.h:90{{candidate function}} |
32 | } |
33 | |
34 | @implementation A |
35 | - (Super*)init { return self; } |
36 | @end |
37 | |
38 | void f(A *a) { |
39 | [a init]; |
40 | } |
41 | |
42 | @class A; |
43 | |
44 | B *f1() { |
45 | return [B create_a_B]; |
46 | } |
47 | |
48 | @class B; |
49 | |
50 | void testProtoMerge(id<P1> p1, id<P2> p2) { |
51 | [p1 protoMethod1]; |
52 | [p2 protoMethod2]; |
53 | } |
54 | |
55 | struct S1 { |
56 | int s1_field; |
57 | }; |
58 | |
59 | struct S3 { |
60 | int s3_field; |
61 | }; |
62 | |
63 | void testTagMerge() { |
64 | consume_S1(produce_S1()); |
65 | struct S2 s2; |
66 | s2.field = 0; |
67 | consume_S2(produce_S2()); |
68 | struct S1 s1; |
69 | s1.s1_field = 0; |
70 | consume_S3(produce_S3()); |
71 | struct S4 s4; |
72 | s4.field = 0; |
73 | consume_S4(produce_S4()); |
74 | struct S3 s3; |
75 | s3.s3_field = 0; |
76 | } |
77 | |
78 | void testTypedefMerge(int i, double d) { |
79 | T1 *ip = &i; |
80 | // FIXME: Typedefs aren't actually merged in the sense of other merges, because |
81 | // we should only merge them when the types are identical. |
82 | // expected-note@Inputs/redecl-merge-left.h:60{{candidate found by name lookup is 'T2'}} |
83 | // expected-note@Inputs/redecl-merge-right.h:63{{candidate found by name lookup is 'T2'}} |
84 | T2 *dp = &d; // expected-error{{reference to 'T2' is ambiguous}} |
85 | } |
86 | |
87 | void testFuncMerge(int i) { |
88 | func0(i); |
89 | func1(i); |
90 | // expected-note@Inputs/redecl-merge-left.h:64{{candidate function}} |
91 | // expected-note@Inputs/redecl-merge-right.h:70{{candidate function}} |
92 | func2(i); // expected-error{{call to 'func2' is ambiguous}} |
93 | } |
94 | |
95 | void testVarMerge(int i) { |
96 | var1 = i; |
97 | // expected-note@Inputs/redecl-merge-left.h:77{{candidate found by name lookup is 'var2'}} |
98 | // expected-note@Inputs/redecl-merge-right.h:77{{candidate found by name lookup is 'var2'}} |
99 | var2 = i; // expected-error{{reference to 'var2' is ambiguous}} |
100 | // expected-note@Inputs/redecl-merge-left.h:79{{candidate found by name lookup is 'var3'}} |
101 | // expected-note@Inputs/redecl-merge-right.h:79{{candidate found by name lookup is 'var3'}} |
102 | var3 = i; // expected-error{{reference to 'var3' is ambiguous}} |
103 | } |
104 | |
105 | // Test redeclarations of entities in explicit submodules, to make |
106 | // sure we're maintaining the declaration chains even when normal name |
107 | // lookup can't see what we're looking for. |
108 | void testExplicit() { |
109 | Explicit *e; |
110 | int *(*fp)(void) = &explicit_func; |
111 | int *ip = explicit_func(); |
112 | |
113 | // FIXME: Should complain about definition not having been imported. |
114 | struct explicit_struct es = { 0 }; |
115 | } |
116 | |
117 | // Test resolution of declarations from multiple modules with no |
118 | // common original declaration. |
119 | void test_C(C *c) { |
120 | c = get_a_C(); |
121 | accept_a_C(c); |
122 | } |
123 | |
124 | void test_C2(C2 *c2) { |
125 | c2 = get_a_C2(); |
126 | accept_a_C2(c2); |
127 | } |
128 | |
129 | void test_C3(C3 *c3) { |
130 | c3 = get_a_C3(); |
131 | accept_a_C3(c3); |
132 | } |
133 | |
134 | C4 *global_C4; |
135 | |
136 | ClassWithDef *cwd1; |
137 | |
138 | @import redecl_merge_left_left; |
139 | |
140 | void test_C4a(C4 *c4) { |
141 | global_C4 = c4 = get_a_C4(); |
142 | accept_a_C4(c4); |
143 | } |
144 | |
145 | void test_ClassWithDef(ClassWithDef *cwd) { |
146 | [cwd method]; |
147 | } |
148 | |
149 | @import redecl_merge_bottom; |
150 | |
151 | void test_C4b() { |
152 | if (&refers_to_C4) { |
153 | } |
154 | } |
155 | |
156 | @implementation B |
157 | + (B*)create_a_B { return 0; } |
158 | @end |
159 | |
160 | void g(A *a) { |
161 | [a init]; |
162 | } |
163 | |
164 | @protocol P3 |
165 | - (void)p3_method; |
166 | @end |
167 | |
168 | id<P4> p4; |
169 | id<P3> p3; |
170 | |
171 | // Make sure we don't get conflicts with 'id'. |
172 | funcptr_with_id fid; |
173 | id id_global; |
174 | |
175 | |
176 | |