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