Rafael Espindola | f5fe292 | 2010-12-07 15:23:23 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm %s -o - -verify | FileCheck %s |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 2 | |
| 3 | // CHECK: @weakvar = weak global |
| 4 | // CHECK: @__weakvar_alias = common global |
| 5 | // CHECK: @correct_linkage = weak global |
| 6 | |
| 7 | |
| 8 | // CHECK: @both = alias void ()* @__both |
| 9 | // CHECK: @both2 = alias void ()* @__both2 |
| 10 | // CHECK: @both3 = alias weak void ()* @__both3 |
| 11 | // CHECK: @a3 = alias weak void ()* @__a3 |
| 12 | // CHECK: @weakvar_alias = alias weak i32* @__weakvar_alias |
| 13 | // CHECK: @foo = alias weak void ()* @__foo |
| 14 | // CHECK: @foo2 = alias weak void ()* @__foo2 |
| 15 | // CHECK: @stutter = alias weak void ()* @__stutter |
| 16 | // CHECK: @stutter2 = alias weak void ()* @__stutter2 |
| 17 | // CHECK: @declfirst = alias weak void ()* @__declfirst |
| 18 | // CHECK: @declfirstattr = alias weak void ()* @__declfirstattr |
| 19 | // CHECK: @mix2 = alias weak void ()* @__mix2 |
| 20 | // CHECK: @a1 = alias weak void ()* @__a1 |
| 21 | // CHECK: @xxx = alias weak void ()* @__xxx |
| 22 | |
| 23 | |
| 24 | |
| 25 | // CHECK: define weak void @weakdef() |
| 26 | |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 27 | |
| 28 | #pragma weak weakvar |
| 29 | int weakvar; |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 30 | |
| 31 | #pragma weak weakdef |
| 32 | void weakdef(void) {} |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 33 | |
| 34 | #pragma weak param // expected-warning {{weak identifier 'param' never declared}} |
| 35 | #pragma weak correct_linkage |
| 36 | void f(int param) { |
| 37 | int correct_linkage; |
| 38 | } |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 39 | |
| 40 | #pragma weak weakvar_alias = __weakvar_alias |
| 41 | int __weakvar_alias; |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 42 | |
| 43 | #pragma weak foo = __foo |
| 44 | void __foo(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 45 | // CHECK: define void @__foo() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 46 | |
| 47 | |
| 48 | void __foo2(void) {} |
| 49 | #pragma weak foo2 = __foo2 |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 50 | // CHECK: define void @__foo2() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 51 | |
| 52 | |
| 53 | ///// test errors |
| 54 | |
| 55 | #pragma weak unused // expected-warning {{weak identifier 'unused' never declared}} |
| 56 | #pragma weak unused_alias = __unused_alias // expected-warning {{weak identifier '__unused_alias' never declared}} |
| 57 | |
| 58 | #pragma weak td // expected-warning {{weak identifier 'td' never declared}} |
| 59 | typedef int td; |
| 60 | |
| 61 | #pragma weak td2 = __td2 // expected-warning {{weak identifier '__td2' never declared}} |
| 62 | typedef int __td2; |
| 63 | |
| 64 | |
| 65 | ///// test weird cases |
| 66 | |
| 67 | // test repeats |
| 68 | |
| 69 | #pragma weak stutter = __stutter |
| 70 | #pragma weak stutter = __stutter |
| 71 | void __stutter(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 72 | // CHECK: define void @__stutter() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 73 | |
| 74 | void __stutter2(void) {} |
| 75 | #pragma weak stutter2 = __stutter2 |
| 76 | #pragma weak stutter2 = __stutter2 |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 77 | // CHECK: define void @__stutter2() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 78 | |
| 79 | |
| 80 | // test decl/pragma weak order |
| 81 | |
| 82 | void __declfirst(void); |
| 83 | #pragma weak declfirst = __declfirst |
| 84 | void __declfirst(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 85 | // CHECK: define void @__declfirst() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 86 | |
| 87 | void __declfirstattr(void) __attribute((noinline)); |
| 88 | #pragma weak declfirstattr = __declfirstattr |
| 89 | void __declfirstattr(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 90 | // CHECK: define void @__declfirstattr() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 91 | |
| 92 | //// test that other attributes are preserved |
| 93 | |
| 94 | //// ensure that pragma weak/__attribute((weak)) play nice |
| 95 | |
| 96 | void mix(void); |
| 97 | #pragma weak mix |
| 98 | __attribute((weak)) void mix(void) { } |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 99 | // CHECK: define weak void @mix() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 100 | |
| 101 | // ensure following __attributes are preserved and that only a single |
| 102 | // alias is generated |
| 103 | #pragma weak mix2 = __mix2 |
| 104 | void __mix2(void) __attribute((noinline)); |
| 105 | void __mix2(void) __attribute((noinline)); |
| 106 | void __mix2(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 107 | // CHECK: define void @__mix2() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 108 | |
| 109 | ////////////// test #pragma weak/__attribute combinations |
| 110 | |
| 111 | // if the SAME ALIAS is already declared then it overrides #pragma weak |
| 112 | // resulting in a non-weak alias in this case |
| 113 | void both(void) __attribute((alias("__both"))); |
| 114 | #pragma weak both = __both |
| 115 | void __both(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 116 | // CHECK: define void @__both() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 117 | |
| 118 | // if the TARGET is previously declared then whichever aliasing method |
| 119 | // comes first applies and subsequent aliases are discarded. |
| 120 | // TODO: warn about this |
| 121 | |
| 122 | void __both2(void); |
| 123 | void both2(void) __attribute((alias("__both2"))); // first, wins |
| 124 | #pragma weak both2 = __both2 |
| 125 | void __both2(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 126 | // CHECK: define void @__both2() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 127 | |
| 128 | void __both3(void); |
| 129 | #pragma weak both3 = __both3 // first, wins |
| 130 | void both3(void) __attribute((alias("__both3"))); |
| 131 | void __both3(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 132 | // CHECK: define void @__both3() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 133 | |
| 134 | ///////////// ensure that #pragma weak does not alter existing __attributes() |
| 135 | |
| 136 | void __a1(void) __attribute((noinline)); |
| 137 | #pragma weak a1 = __a1 |
| 138 | void __a1(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 139 | // CHECK: define void @__a1() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 140 | |
| 141 | // attributes introduced BEFORE a combination of #pragma weak and alias() |
| 142 | // hold... |
| 143 | void __a3(void) __attribute((noinline)); |
| 144 | #pragma weak a3 = __a3 |
| 145 | void a3(void) __attribute((alias("__a3"))); |
| 146 | void __a3(void) {} |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 147 | // CHECK: define void @__a3() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 148 | |
| 149 | #pragma weak xxx = __xxx |
| 150 | __attribute((pure,noinline,const,fastcall)) void __xxx(void) { } |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 151 | // CHECK: void @__xxx() |
Ryan Flynn | 8f6e88f | 2009-08-03 23:16:15 +0000 | [diff] [blame] | 152 | |
| 153 | /// TODO: stuff that still doesn't work |
| 154 | |
| 155 | // due to the fact that disparate TopLevelDecls cannot affect each other |
| 156 | // (due to clang's Parser and ASTConsumer behavior, and quite reasonable) |
| 157 | // #pragma weak must appear before or within the same TopLevelDecl as it |
| 158 | // references. |
| 159 | void yyy(void){} |
| 160 | void zzz(void){} |
| 161 | #pragma weak yyy |
| 162 | // NOTE: weak doesn't apply, not before or in same TopLevelDec(!) |
Chris Lattner | 60e8188 | 2009-09-08 18:43:45 +0000 | [diff] [blame] | 163 | // CHECK: define void @yyy() |
| 164 | |
| 165 | int correct_linkage; |