Home | History | Annotate | Download | only in CodeGen
      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