Home | History | Annotate | Download | only in testsuite
      1 // basic_test.cc -- a test case for gold
      2 
      3 // Copyright (C) 2006-2016 Free Software Foundation, Inc.
      4 // Written by Ian Lance Taylor <iant (at) google.com>.
      5 
      6 // This file is part of gold.
      7 
      8 // This program is free software; you can redistribute it and/or modify
      9 // it under the terms of the GNU General Public License as published by
     10 // the Free Software Foundation; either version 3 of the License, or
     11 // (at your option) any later version.
     12 
     13 // This program is distributed in the hope that it will be useful,
     14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 // GNU General Public License for more details.
     17 
     18 // You should have received a copy of the GNU General Public License
     19 // along with this program; if not, write to the Free Software
     20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21 // MA 02110-1301, USA.
     22 
     23 // The goal of this program is to produce as many different types of
     24 // relocations as we can in a stand-alone program that does not use
     25 // TLS.  This program is compiled without optimization.
     26 
     27 // 1  Code reference to global data.
     28 // 2  Code reference to static data.
     29 // 3  Code reference to BSS data.
     30 // 4  Code reference to offset within global data.
     31 // 5  Code reference to offset within static data.
     32 // 6  Code reference to offset within BSS data.
     33 // 7  Switch statement with a table of destinations.
     34 // 8  Taking the address of a label (a gcc extension).
     35 // 9  Taking the address of a nested function (a gcc extension).
     36 // 10 Data reference to global data.
     37 // 11 Data reference to static data.
     38 // 12 Data reference to BSS data.
     39 // 13 Data reference to offset within global data.
     40 // 14 Data reference to offset within static data.
     41 // 15 Data reference to offset within BSS data.
     42 // 16 Virtual table.
     43 // 17 Inline function.
     44 // 18 Call through pointer to method.
     45 // 19 Initialize variable to pointer to method.
     46 // 20 Global constructor and destructor.
     47 
     48 // 1 Code reference to global data.
     49 int t1 = 11;
     50 
     51 // 2 Code reference to static data.
     52 static int t2 = 22;
     53 
     54 // 3 Code reference to BSS data (initialized after program starts, to
     55 // 33).
     56 int t3;
     57 
     58 // 4 Code reference to offset within global data.
     59 char t4[] = "Hello, world";
     60 
     61 // 5 Code reference to offset within static data.
     62 static char t5[] = "Hello, world";
     63 
     64 // 6 Code reference to offset within BSS data (initialized after
     65 // program starts, to contents of t4).
     66 char t6[13];
     67 
     68 // Test cases 1 through 6.
     69 
     70 bool
     71 t1_6()
     72 {
     73   return (t1 == 11
     74 	  && t2 == 22
     75 	  && t3 == 33
     76 	  && t4[5] == ','
     77 	  && t5[7] == 'w'
     78 	  && t6[9] == 'r');
     79 }
     80 
     81 // 7  Switch statement with a table of destinations.
     82 
     83 int
     84 t7(int i)
     85 {
     86   switch (i)
     87     {
     88     case 0:
     89       return 12;
     90     case 1:
     91       return 34;
     92     case 2:
     93       return 56;
     94     case 3:
     95       return 78;
     96     case 4:
     97       return 90;
     98     case 5:
     99       return 13;
    100     case 6:
    101       return 0;
    102     case 7:
    103       return 57;
    104     case 8:
    105       return 79;
    106     case 9:
    107       return 81;
    108     default:
    109       return 144;
    110     }
    111 }
    112 
    113 // 8  Taking the address of a label (a gcc extension).
    114 
    115 int
    116 t8(int i)
    117 {
    118   for (int j = 0; j < 10; ++j)
    119     {
    120       void* p;
    121       if (i + j > 6)
    122 	p = &&lab1;
    123       else
    124 	p = &&lab2;
    125       if (j == 7)
    126 	goto *p;
    127     }
    128   return 15;
    129  lab1:
    130   return 0;
    131  lab2:
    132   return 12;
    133 }
    134 
    135 // 9  Taking the address of a nested function (a gcc extension).
    136 // Disabled because this is only supported in C, not C++.
    137 
    138 int
    139 t9a(int (*pfn)(int))
    140 {
    141   return (*pfn)(10) - 10;
    142 }
    143 
    144 int
    145 t9(int i)
    146 {
    147 #if 0
    148   int
    149   t9c(int j)
    150   {
    151     return i + j;
    152   }
    153   return t9a(&t9c);
    154 #else
    155   return i;
    156 #endif
    157 }
    158 
    159 // 10 Data reference to global data.
    160 int* t10 = &t1;
    161 
    162 // 11 Data reference to static data.
    163 int* t11 = &t2;
    164 
    165 // 12 Data reference to BSS data.
    166 int* t12 = &t3;
    167 
    168 // 13 Data reference to offset within global data.
    169 char* t13 = &t4[6];
    170 
    171 // 14 Data reference to offset within static data.
    172 char* t14 = &t5[8];
    173 
    174 // 15 Data reference to offset within BSS data.
    175 char* t15 = &t6[10];
    176 
    177 // Test cases 10 through 15.
    178 
    179 bool
    180 t10_15()
    181 {
    182   return (*t10 == 11
    183 	  && *t11 == 22
    184 	  && *t12 == 33
    185 	  && *t13 == ' '
    186 	  && *t14 == 'o'
    187 	  && *t15 == 'l');
    188 }
    189 
    190 // 16 Virtual table.
    191 
    192 class t16a
    193 {
    194  public:
    195   virtual
    196   ~t16a()
    197   { }
    198   virtual int
    199   t()
    200   { return 83; }
    201 };
    202 
    203 class t16b : public t16a
    204 {
    205  public:
    206   virtual int
    207   t()
    208   { return 92; }
    209 };
    210 
    211 t16b t16v;
    212 
    213 bool
    214 t16()
    215 {
    216   return t16v.t() == 92;
    217 }
    218 
    219 // 17 Inline function.
    220 
    221 inline int
    222 t17a()
    223 {
    224   return 74;
    225 }
    226 
    227 bool
    228 t17()
    229 {
    230   return t17a() == 74;
    231 }
    232 
    233 // 18 Call through pointer to method.
    234 
    235 class t18a
    236 {
    237  public:
    238   int
    239   ta()
    240   { return 65; }
    241 
    242   int
    243   tb()
    244   { return 90; }
    245 };
    246 
    247 t18a t18v;
    248 
    249 int
    250 t18f(int (t18a::* p)())
    251 {
    252   return (t18v.*p)();
    253 }
    254 
    255 bool
    256 t18()
    257 {
    258   return t18f(&t18a::ta) == 65;
    259 }
    260 
    261 // 19 Initialize variable to pointer to method.
    262 
    263 int (t18a::* t19v)() = &t18a::tb;
    264 
    265 bool
    266 t19()
    267 {
    268   return (t18v.*t19v)() == 90;
    269 }
    270 
    271 // 20 Global constructor and destructor.
    272 
    273 class t20a
    274 {
    275  public:
    276   t20a()
    277     : i(96)
    278   { }
    279   ~t20a()
    280   { }
    281   int
    282   get() const
    283   { return this->i; }
    284  private:
    285   int i;
    286 };
    287 
    288 t20a t20v;
    289 
    290 bool
    291 t20()
    292 {
    293   return t20v.get() == 96;
    294 }
    295 
    296 // Main function.  Initialize variables and call test functions.
    297 
    298 int
    299 main()
    300 {
    301   t3 = 33;
    302   for (int i = 0; i < 13; ++i)
    303     t6[i] = t4[i];
    304 
    305   if (t1_6()
    306       && t7(6) == 0
    307       && t8(0) == 0
    308       && t9(5) == 5
    309       && t10_15()
    310       && t16()
    311       && t17()
    312       && t18()
    313       && t19()
    314       && t20())
    315     return 0;
    316   else
    317     return 1;
    318 }
    319