| 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 | |