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 = global
5 // CHECK: @correct_linkage = weak global
6 
7 
8 // CHECK-DAG: @both = alias void (), void ()* @__both
9 // CHECK-DAG: @both2 = alias void (), void ()* @__both2
10 // CHECK-DAG: @weakvar_alias = weak alias i32, i32* @__weakvar_alias
11 // CHECK-DAG: @foo = weak alias void (), void ()* @__foo
12 // CHECK-DAG: @foo2 = weak alias void (), void ()* @__foo2
13 // CHECK-DAG: @stutter = weak alias void (), void ()* @__stutter
14 // CHECK-DAG: @stutter2 = weak alias void (), void ()* @__stutter2
15 // CHECK-DAG: @declfirst = weak alias void (), void ()* @__declfirst
16 // CHECK-DAG: @declfirstattr = weak alias void (), void ()* @__declfirstattr
17 // CHECK-DAG: @mix2 = weak alias void (), void ()* @__mix2
18 // CHECK-DAG: @a1 = weak alias void (), void ()* @__a1
19 // CHECK-DAG: @xxx = weak alias void (), void ()* @__xxx
20 
21 
22 
23 // CHECK-LABEL: define weak void @weakdef()
24 
25 
26 #pragma weak weakvar
27 int weakvar;
28 
29 #pragma weak weakdef
weakdef(void)30 void weakdef(void) {}
31 
32 #pragma weak param // expected-warning {{weak identifier 'param' never declared}}
33 #pragma weak correct_linkage
f(int param)34 void f(int param) {
35   int correct_linkage;
36 }
37 
38 #pragma weak weakvar_alias = __weakvar_alias
39 int __weakvar_alias;
40 
41 #pragma weak foo = __foo
__foo(void)42 void __foo(void) {}
43 // CHECK-LABEL: define void @__foo()
44 
45 
__foo2(void)46 void __foo2(void) {}
47 #pragma weak foo2 = __foo2
48 // CHECK-LABEL: define void @__foo2()
49 
50 
51 ///// test errors
52 
53 #pragma weak unused // expected-warning {{weak identifier 'unused' never declared}}
54 #pragma weak unused_alias = __unused_alias  // expected-warning {{weak identifier '__unused_alias' never declared}}
55 
56 #pragma weak td // expected-warning {{'weak' attribute only applies to variables and functions}}
57 typedef int td;
58 
59 #pragma weak td2 = __td2 // expected-warning {{'weak' attribute only applies to variables and functions}}
60 typedef int __td2;
61 
62 typedef int __td3;
63 #pragma weak td3 = __td3 // expected-warning {{'weak' attribute only applies to variables and functions}}
64 
65 ///// test weird cases
66 
67 // test repeats
68 
69 #pragma weak stutter = __stutter
70 #pragma weak stutter = __stutter
__stutter(void)71 void __stutter(void) {}
72 // CHECK-LABEL: define void @__stutter()
73 
__stutter2(void)74 void __stutter2(void) {}
75 #pragma weak stutter2 = __stutter2
76 #pragma weak stutter2 = __stutter2
77 // CHECK-LABEL: define void @__stutter2()
78 
79 
80 // test decl/pragma weak order
81 
82 void __declfirst(void);
83 #pragma weak declfirst = __declfirst
__declfirst(void)84 void __declfirst(void) {}
85 // CHECK-LABEL: define void @__declfirst()
86 
87 void __declfirstattr(void) __attribute((noinline));
88 #pragma weak declfirstattr = __declfirstattr
__declfirstattr(void)89 void __declfirstattr(void) {}
90 // CHECK-LABEL: 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
mix(void)98 __attribute((weak)) void mix(void) { }
99 // CHECK-LABEL: 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));
__mix2(void)106 void __mix2(void) {}
107 // CHECK-LABEL: 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
__both(void)115 void __both(void) {}
116 // CHECK-LABEL: 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
__both2(void)125 void __both2(void) {}
126 // CHECK-LABEL: define void @__both2()
127 
128 ///////////// ensure that #pragma weak does not alter existing __attributes()
129 
130 void __a1(void) __attribute((noinline));
131 #pragma weak a1 = __a1
__a1(void)132 void __a1(void) {}
133 // CHECK: define void @__a1() [[NI:#[0-9]+]]
134 
135 #pragma weak xxx = __xxx
__xxx(void)136 __attribute((pure,noinline,const)) void __xxx(void) { }
137 // CHECK: void @__xxx() [[RN:#[0-9]+]]
138 
139 ///////////// PR10878: Make sure we can call a weak alias
SHA512Pad(void * context)140 void SHA512Pad(void *context) {}
141 #pragma weak SHA384Pad = SHA512Pad
PR10878()142 void PR10878() { SHA384Pad(0); }
143 // CHECK: call void @SHA384Pad(i8* null)
144 
145 
146 // PR14046: Parse #pragma weak in function-local context
147 extern int PR14046e(void);
PR14046f()148 void PR14046f() {
149 #pragma weak PR14046e
150   PR14046e();
151 }
152 // CHECK: declare extern_weak i32 @PR14046e()
153 
154 // Parse #pragma weak after a label or case statement
155 extern int PR16705a(void);
156 extern int PR16705b(void);
157 extern int PR16705c(void);
PR16705f(int a)158 void PR16705f(int a) {
159   switch(a) {
160   case 1:
161 #pragma weak PR16705a
162     PR16705a();
163   default:
164 #pragma weak PR16705b
165     PR16705b();
166   }
167 label:
168   #pragma weak PR16705c
169   PR16705c();
170 }
171 
172 // CHECK: declare extern_weak i32 @PR16705a()
173 // CHECK: declare extern_weak i32 @PR16705b()
174 // CHECK: declare extern_weak i32 @PR16705c()
175 
176 
177 ///////////// TODO: stuff that still doesn't work
178 
179 // due to the fact that disparate TopLevelDecls cannot affect each other
180 // (due to clang's Parser and ASTConsumer behavior, and quite reasonable)
181 // #pragma weak must appear before or within the same TopLevelDecl as it
182 // references.
yyy(void)183 void yyy(void){}
zzz(void)184 void zzz(void){}
185 #pragma weak yyy
186 // NOTE: weak doesn't apply, not before or in same TopLevelDec(!)
187 // CHECK-LABEL: define void @yyy()
188 
189 int correct_linkage;
190 
191 // CHECK: attributes [[NI]] = { noinline nounwind{{.*}} }
192 // CHECK: attributes [[RN]] = { noinline nounwind optnone readnone{{.*}} }
193