1 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm %s -o - -verify | FileCheck %s
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 
27 
28 #pragma weak weakvar
29 int weakvar;
30 
31 #pragma weak weakdef
32 void weakdef(void) {}
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 }
39 
40 #pragma weak weakvar_alias = __weakvar_alias
41 int __weakvar_alias;
42 
43 #pragma weak foo = __foo
44 void __foo(void) {}
45 // CHECK: define void @__foo()
46 
47 
48 void __foo2(void) {}
49 #pragma weak foo2 = __foo2
50 // CHECK: define void @__foo2()
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) {}
72 // CHECK: define void @__stutter()
73 
74 void __stutter2(void) {}
75 #pragma weak stutter2 = __stutter2
76 #pragma weak stutter2 = __stutter2
77 // CHECK: define void @__stutter2()
78 
79 
80 // test decl/pragma weak order
81 
82 void __declfirst(void);
83 #pragma weak declfirst = __declfirst
84 void __declfirst(void) {}
85 // CHECK: define void @__declfirst()
86 
87 void __declfirstattr(void) __attribute((noinline));
88 #pragma weak declfirstattr = __declfirstattr
89 void __declfirstattr(void) {}
90 // CHECK: define void @__declfirstattr()
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) { }
99 // CHECK: define weak void @mix()
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) {}
107 // CHECK: define void @__mix2()
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) {}
116 // CHECK: define void @__both()
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) {}
126 // CHECK: define void @__both2()
127 
128 void __both3(void);
129 #pragma weak both3 = __both3 // first, wins
130 void both3(void) __attribute((alias("__both3")));
131 void __both3(void) {}
132 // CHECK: define void @__both3()
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) {}
139 // CHECK: define void @__a1() [[NI:#[0-9]+]]
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) {}
147 // CHECK: define void @__a3() [[NI]]
148 
149 #pragma weak xxx = __xxx
150 __attribute((pure,noinline,const,fastcall)) void __xxx(void) { }
151 // CHECK: void @__xxx() [[RN:#[0-9]+]]
152 
153 ///////////// PR10878: Make sure we can call a weak alias
154 void SHA512Pad(void *context) {}
155 #pragma weak SHA384Pad = SHA512Pad
156 void PR10878() { SHA384Pad(0); }
157 // CHECK: call void @SHA384Pad(i8* null)
158 
159 
160 // PR14046: Parse #pragma weak in function-local context
161 extern int PR14046e(void);
162 void PR14046f() {
163 #pragma weak PR14046e
164   PR14046e();
165 }
166 // CHECK: declare extern_weak i32 @PR14046e()
167 
168 
169 ///////////// TODO: stuff that still doesn't work
170 
171 // due to the fact that disparate TopLevelDecls cannot affect each other
172 // (due to clang's Parser and ASTConsumer behavior, and quite reasonable)
173 // #pragma weak must appear before or within the same TopLevelDecl as it
174 // references.
175 void yyy(void){}
176 void zzz(void){}
177 #pragma weak yyy
178 // NOTE: weak doesn't apply, not before or in same TopLevelDec(!)
179 // CHECK: define void @yyy()
180 
181 int correct_linkage;
182 
183 // CHECK: attributes [[NI]] = { noinline nounwind{{.*}} }
184 // CHECK: attributes [[RN]] = { noinline nounwind readnone{{.*}} }
185