]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/pragma-weak.c
Vendor import of clang RELEASE_360/rc1 tag r226102 (effectively, 3.6.0 RC1):
[FreeBSD/FreeBSD.git] / test / CodeGen / pragma-weak.c
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-DAG: @both = alias void ()* @__both
9 // CHECK-DAG: @both2 = alias void ()* @__both2
10 // CHECK-DAG: @weakvar_alias = weak alias i32* @__weakvar_alias
11 // CHECK-DAG: @foo = weak alias void ()* @__foo
12 // CHECK-DAG: @foo2 = weak alias void ()* @__foo2
13 // CHECK-DAG: @stutter = weak alias void ()* @__stutter
14 // CHECK-DAG: @stutter2 = weak alias void ()* @__stutter2
15 // CHECK-DAG: @declfirst = weak alias void ()* @__declfirst
16 // CHECK-DAG: @declfirstattr = weak alias void ()* @__declfirstattr
17 // CHECK-DAG: @mix2 = weak alias void ()* @__mix2
18 // CHECK-DAG: @a1 = weak alias void ()* @__a1
19 // CHECK-DAG: @xxx = weak alias 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
30 void weakdef(void) {}
31
32 #pragma weak param // expected-warning {{weak identifier 'param' never declared}}
33 #pragma weak correct_linkage
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
42 void __foo(void) {}
43 // CHECK-LABEL: define void @__foo()
44
45
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 identifier 'td' never declared}}
57 typedef int td;
58
59 #pragma weak td2 = __td2 // expected-warning {{weak identifier '__td2' never declared}}
60 typedef int __td2;
61
62
63 ///// test weird cases
64
65 // test repeats
66
67 #pragma weak stutter = __stutter
68 #pragma weak stutter = __stutter
69 void __stutter(void) {}
70 // CHECK-LABEL: define void @__stutter()
71
72 void __stutter2(void) {}
73 #pragma weak stutter2 = __stutter2
74 #pragma weak stutter2 = __stutter2
75 // CHECK-LABEL: define void @__stutter2()
76
77
78 // test decl/pragma weak order
79
80 void __declfirst(void);
81 #pragma weak declfirst = __declfirst
82 void __declfirst(void) {}
83 // CHECK-LABEL: define void @__declfirst()
84
85 void __declfirstattr(void) __attribute((noinline));
86 #pragma weak declfirstattr = __declfirstattr
87 void __declfirstattr(void) {}
88 // CHECK-LABEL: define void @__declfirstattr()
89
90 //// test that other attributes are preserved
91
92 //// ensure that pragma weak/__attribute((weak)) play nice
93
94 void mix(void);
95 #pragma weak mix
96 __attribute((weak)) void mix(void) { }
97 // CHECK-LABEL: define weak void @mix()
98
99 // ensure following __attributes are preserved and that only a single
100 // alias is generated
101 #pragma weak mix2 = __mix2
102 void __mix2(void) __attribute((noinline));
103 void __mix2(void) __attribute((noinline));
104 void __mix2(void) {}
105 // CHECK-LABEL: define void @__mix2()
106
107 ////////////// test #pragma weak/__attribute combinations
108
109 // if the SAME ALIAS is already declared then it overrides #pragma weak
110 // resulting in a non-weak alias in this case
111 void both(void) __attribute((alias("__both")));
112 #pragma weak both = __both
113 void __both(void) {}
114 // CHECK-LABEL: define void @__both()
115
116 // if the TARGET is previously declared then whichever aliasing method
117 // comes first applies and subsequent aliases are discarded.
118 // TODO: warn about this
119
120 void __both2(void);
121 void both2(void) __attribute((alias("__both2"))); // first, wins
122 #pragma weak both2 = __both2
123 void __both2(void) {}
124 // CHECK-LABEL: define void @__both2()
125
126 ///////////// ensure that #pragma weak does not alter existing __attributes()
127
128 void __a1(void) __attribute((noinline));
129 #pragma weak a1 = __a1
130 void __a1(void) {}
131 // CHECK: define void @__a1() [[NI:#[0-9]+]]
132
133 #pragma weak xxx = __xxx
134 __attribute((pure,noinline,const)) void __xxx(void) { }
135 // CHECK: void @__xxx() [[RN:#[0-9]+]]
136
137 ///////////// PR10878: Make sure we can call a weak alias
138 void SHA512Pad(void *context) {}
139 #pragma weak SHA384Pad = SHA512Pad
140 void PR10878() { SHA384Pad(0); }
141 // CHECK: call void @SHA384Pad(i8* null)
142
143
144 // PR14046: Parse #pragma weak in function-local context
145 extern int PR14046e(void);
146 void PR14046f() {
147 #pragma weak PR14046e
148   PR14046e();
149 }
150 // CHECK: declare extern_weak i32 @PR14046e()
151
152 // Parse #pragma weak after a label or case statement
153 extern int PR16705a(void);
154 extern int PR16705b(void);
155 extern int PR16705c(void);
156 void PR16705f(int a) {
157   switch(a) {
158   case 1:
159 #pragma weak PR16705a
160     PR16705a();
161   default:
162 #pragma weak PR16705b
163     PR16705b();
164   }
165 label:
166   #pragma weak PR16705c
167   PR16705c();
168 }
169
170 // CHECK: declare extern_weak i32 @PR16705a()
171 // CHECK: declare extern_weak i32 @PR16705b()
172 // CHECK: declare extern_weak i32 @PR16705c()
173
174
175 ///////////// TODO: stuff that still doesn't work
176
177 // due to the fact that disparate TopLevelDecls cannot affect each other
178 // (due to clang's Parser and ASTConsumer behavior, and quite reasonable)
179 // #pragma weak must appear before or within the same TopLevelDecl as it
180 // references.
181 void yyy(void){}
182 void zzz(void){}
183 #pragma weak yyy
184 // NOTE: weak doesn't apply, not before or in same TopLevelDec(!)
185 // CHECK-LABEL: define void @yyy()
186
187 int correct_linkage;
188
189 // CHECK: attributes [[NI]] = { noinline nounwind{{.*}} }
190 // CHECK: attributes [[RN]] = { noinline nounwind readnone{{.*}} }