| // basic_test.cc -- a test case for gold |
| |
| // Copyright (C) 2006-2024 Free Software Foundation, Inc. |
| // Written by Ian Lance Taylor <iant@google.com>. |
| |
| // This file is part of gold. |
| |
| // This program is free software; you can redistribute it and/or modify |
| // it under the terms of the GNU General Public License as published by |
| // the Free Software Foundation; either version 3 of the License, or |
| // (at your option) any later version. |
| |
| // This program is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU General Public License for more details. |
| |
| // You should have received a copy of the GNU General Public License |
| // along with this program; if not, write to the Free Software |
| // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| // MA 02110-1301, USA. |
| |
| // The goal of this program is to produce as many different types of |
| // relocations as we can in a stand-alone program that does not use |
| // TLS. This program is compiled without optimization. |
| |
| // 1 Code reference to global data. |
| // 2 Code reference to static data. |
| // 3 Code reference to BSS data. |
| // 4 Code reference to offset within global data. |
| // 5 Code reference to offset within static data. |
| // 6 Code reference to offset within BSS data. |
| // 7 Switch statement with a table of destinations. |
| // 8 Taking the address of a label (a gcc extension). |
| // 9 Taking the address of a nested function (a gcc extension). |
| // 10 Data reference to global data. |
| // 11 Data reference to static data. |
| // 12 Data reference to BSS data. |
| // 13 Data reference to offset within global data. |
| // 14 Data reference to offset within static data. |
| // 15 Data reference to offset within BSS data. |
| // 16 Virtual table. |
| // 17 Inline function. |
| // 18 Call through pointer to method. |
| // 19 Initialize variable to pointer to method. |
| // 20 Global constructor and destructor. |
| |
| // 1 Code reference to global data. |
| int t1 = 11; |
| |
| // 2 Code reference to static data. |
| static int t2 = 22; |
| |
| // 3 Code reference to BSS data (initialized after program starts, to |
| // 33). |
| int t3; |
| |
| // 4 Code reference to offset within global data. |
| char t4[] = "Hello, world"; |
| |
| // 5 Code reference to offset within static data. |
| static char t5[] = "Hello, world"; |
| |
| // 6 Code reference to offset within BSS data (initialized after |
| // program starts, to contents of t4). |
| char t6[13]; |
| |
| // Test cases 1 through 6. |
| |
| bool |
| t1_6() |
| { |
| return (t1 == 11 |
| && t2 == 22 |
| && t3 == 33 |
| && t4[5] == ',' |
| && t5[7] == 'w' |
| && t6[9] == 'r'); |
| } |
| |
| // 7 Switch statement with a table of destinations. |
| |
| int |
| t7(int i) |
| { |
| switch (i) |
| { |
| case 0: |
| return 12; |
| case 1: |
| return 34; |
| case 2: |
| return 56; |
| case 3: |
| return 78; |
| case 4: |
| return 90; |
| case 5: |
| return 13; |
| case 6: |
| return 0; |
| case 7: |
| return 57; |
| case 8: |
| return 79; |
| case 9: |
| return 81; |
| default: |
| return 144; |
| } |
| } |
| |
| // 8 Taking the address of a label (a gcc extension). |
| |
| int |
| t8(int i) |
| { |
| for (int j = 0; j < 10; ++j) |
| { |
| void* p; |
| if (i + j > 6) |
| p = &&lab1; |
| else |
| p = &&lab2; |
| if (j == 7) |
| goto *p; |
| } |
| return 15; |
| lab1: |
| return 0; |
| lab2: |
| return 12; |
| } |
| |
| // 9 Taking the address of a nested function (a gcc extension). |
| // Disabled because this is only supported in C, not C++. |
| |
| int |
| t9a(int (*pfn)(int)) |
| { |
| return (*pfn)(10) - 10; |
| } |
| |
| int |
| t9(int i) |
| { |
| #if 0 |
| int |
| t9c(int j) |
| { |
| return i + j; |
| } |
| return t9a(&t9c); |
| #else |
| return i; |
| #endif |
| } |
| |
| // 10 Data reference to global data. |
| int* t10 = &t1; |
| |
| // 11 Data reference to static data. |
| int* t11 = &t2; |
| |
| // 12 Data reference to BSS data. |
| int* t12 = &t3; |
| |
| // 13 Data reference to offset within global data. |
| char* t13 = &t4[6]; |
| |
| // 14 Data reference to offset within static data. |
| char* t14 = &t5[8]; |
| |
| // 15 Data reference to offset within BSS data. |
| char* t15 = &t6[10]; |
| |
| // Test cases 10 through 15. |
| |
| bool |
| t10_15() |
| { |
| return (*t10 == 11 |
| && *t11 == 22 |
| && *t12 == 33 |
| && *t13 == ' ' |
| && *t14 == 'o' |
| && *t15 == 'l'); |
| } |
| |
| // 16 Virtual table. |
| |
| class t16a |
| { |
| public: |
| virtual |
| ~t16a() |
| { } |
| virtual int |
| t() |
| { return 83; } |
| }; |
| |
| class t16b : public t16a |
| { |
| public: |
| virtual int |
| t() |
| { return 92; } |
| }; |
| |
| t16b t16v; |
| |
| bool |
| t16() |
| { |
| return t16v.t() == 92; |
| } |
| |
| // 17 Inline function. |
| |
| inline int |
| t17a() |
| { |
| return 74; |
| } |
| |
| bool |
| t17() |
| { |
| return t17a() == 74; |
| } |
| |
| // 18 Call through pointer to method. |
| |
| class t18a |
| { |
| public: |
| int |
| ta() |
| { return 65; } |
| |
| int |
| tb() |
| { return 90; } |
| }; |
| |
| t18a t18v; |
| |
| int |
| t18f(int (t18a::* p)()) |
| { |
| return (t18v.*p)(); |
| } |
| |
| bool |
| t18() |
| { |
| return t18f(&t18a::ta) == 65; |
| } |
| |
| // 19 Initialize variable to pointer to method. |
| |
| int (t18a::* t19v)() = &t18a::tb; |
| |
| bool |
| t19() |
| { |
| return (t18v.*t19v)() == 90; |
| } |
| |
| // 20 Global constructor and destructor. |
| |
| class t20a |
| { |
| public: |
| t20a() |
| : i(96) |
| { } |
| ~t20a() |
| { } |
| int |
| get() const |
| { return this->i; } |
| private: |
| int i; |
| }; |
| |
| t20a t20v; |
| |
| bool |
| t20() |
| { |
| return t20v.get() == 96; |
| } |
| |
| // Main function. Initialize variables and call test functions. |
| |
| int |
| main() |
| { |
| t3 = 33; |
| for (int i = 0; i < 13; ++i) |
| t6[i] = t4[i]; |
| |
| if (t1_6() |
| && t7(6) == 0 |
| && t8(0) == 0 |
| && t9(5) == 5 |
| && t10_15() |
| && t16() |
| && t17() |
| && t18() |
| && t19() |
| && t20()) |
| return 0; |
| else |
| return 1; |
| } |