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-DAG: @both = alias void ()* @__both
      9 // CHECK-DAG: @both2 = alias void ()* @__both2
     10 // CHECK-DAG: @weakvar_alias = alias weak i32* @__weakvar_alias
     11 // CHECK-DAG: @foo = alias weak void ()* @__foo
     12 // CHECK-DAG: @foo2 = alias weak void ()* @__foo2
     13 // CHECK-DAG: @stutter = alias weak void ()* @__stutter
     14 // CHECK-DAG: @stutter2 = alias weak void ()* @__stutter2
     15 // CHECK-DAG: @declfirst = alias weak void ()* @__declfirst
     16 // CHECK-DAG: @declfirstattr = alias weak void ()* @__declfirstattr
     17 // CHECK-DAG: @mix2 = alias weak void ()* @__mix2
     18 // CHECK-DAG: @a1 = alias weak void ()* @__a1
     19 // CHECK-DAG: @xxx = alias weak 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{{.*}} }
    191