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