1# Copyright 2018-2023 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16# This file is part of the gdb testsuite 17 18# This tests that C++ alignof works in gdb, and that it agrees with 19# the compiler. 20 21if {[skip_cplus_tests]} { continue } 22 23# The types we're going to test. 24 25set typelist { 26 char {unsigned char} 27 short {unsigned short} 28 int {unsigned int} 29 long {unsigned long} 30 {long long} {unsigned long long} 31 float 32 double {long double} 33 empty 34 bigenum 35 vstruct 36 bfstruct 37 arrstruct 38 derived 39 derived2 40} 41 42if {[has_int128_cxx]} { 43 # Note we don't check "unsigned __int128" yet because at least gcc 44 # canonicalizes the name to "__int128 unsigned", and there isn't a 45 # c-exp.y production for this. 46 # https://sourceware.org/bugzilla/show_bug.cgi?id=20991 47 lappend typelist __int128 48} 49 50# Create the test file. 51 52set filename [standard_output_file align.cc] 53set outfile [open $filename w] 54 55# Prologue. 56puts $outfile { 57 template<typename T, typename U> 58 struct align_pair 59 { 60 T one; 61 U two; 62 }; 63 64 template<typename T, typename U> 65 struct align_union 66 { 67 T one; 68 U two; 69 }; 70 71 enum bigenum { VALUE = 0xffffffffull }; 72 73 struct empty { }; 74 75 struct vstruct { virtual ~vstruct() {} char c; }; 76 77 struct bfstruct { unsigned b : 3; }; 78 79 struct arrstruct { short fld[7]; }; 80 81 unsigned a_int3 = alignof (int[3]); 82 83#if defined __GNUC__ && !defined __clang__ 84 /* As a GNU C extension, GCC allows void pointer arithmetic, with 85 sizeof (void) == 1. 86 Another GNU C extension is __alignof__, which can be used to get 87 __alignof__ (void), which is also 1. This is unavailabe on clang. 88 GCC used to only warn for alignof (void), but starting with GCC 12.1, 89 as well as GCC 11.3, it will generate an error (note that using 90 -std=gnu++11 does not prevent the error). 91 So we avoid using alignof, and use __alignof__ instead. */ 92 unsigned a_void = __alignof__ (void); 93#else 94 /* No support for __alignof__ (void), hardcode value. */ 95 unsigned a_void = 1; 96#endif 97 98 struct base { char c; }; 99 struct derived : public virtual base { int i; }; 100 101 struct b2 : public virtual base { char d; }; 102 struct derived2 : public b2, derived { char e; }; 103} 104 105# First emit single items. 106foreach type $typelist { 107 set utype [join [split $type] _] 108 puts $outfile "$type item_$utype;" 109 puts $outfile "unsigned a_$utype\n = alignof ($type);" 110 puts $outfile "typedef $type t_$utype;" 111 puts $outfile "t_$utype item_t_$utype;" 112} 113 114# Now emit all pairs. 115foreach type $typelist { 116 set utype [join [split $type] _] 117 foreach inner $typelist { 118 set uinner [join [split $inner] _] 119 puts $outfile "align_pair<$type, $inner> item_${utype}_x_${uinner};" 120 puts $outfile "unsigned a_${utype}_x_${uinner}" 121 puts $outfile " = alignof (align_pair<$type, $inner>);" 122 123 puts $outfile "align_union<$type, $inner> item_${utype}_u_${uinner};" 124 puts $outfile "unsigned a_${utype}_u_${uinner}" 125 puts $outfile " = alignof (align_union<$type, $inner>);" 126 } 127} 128 129# Epilogue. 130puts $outfile { 131 int main() { 132 return 0; 133 } 134} 135 136close $outfile 137 138standard_testfile $filename 139 140if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ 141 {debug nowarnings c++ additional_flags=-std=c++11}]} { 142 return -1 143} 144 145if {![runto_main]} { 146 perror "test suppressed" 147 return 148} 149 150proc maybe_xfail {type} { 151 # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 152 # The g++ implementation of alignof is changing to match C11. 153 if {[is_x86_like_target] 154 && [test_compiler_info {gcc-[0-8]-*}] 155 && ($type == "double" || $type == "long long" 156 || $type == "unsigned long long")} { 157 setup_xfail *-*-* 158 } 159} 160 161foreach type $typelist { 162 set utype [join [split $type] _] 163 set expected [get_integer_valueof a_$utype 0] 164 165 maybe_xfail $type 166 gdb_test "print alignof($type)" " = $expected" 167 168 maybe_xfail $type 169 gdb_test "print alignof(t_$utype)" " = $expected" 170 171 maybe_xfail $type 172 gdb_test "print alignof(typeof(item_$utype))" " = $expected" 173 174 foreach inner $typelist { 175 set uinner [join [split $inner] _] 176 set expected [get_integer_valueof a_${utype}_x_${uinner} 0] 177 gdb_test "print alignof(align_pair<${type},${inner}>)" " = $expected" 178 179 set expected [get_integer_valueof a_${utype}_u_${uinner} 0] 180 gdb_test "print alignof(align_union<${type},${inner}>)" " = $expected" 181 } 182} 183 184set expected [get_integer_valueof a_int3 0] 185gdb_test "print alignof(int\[3\])" " = $expected" 186 187set expected [get_integer_valueof a_void 0] 188gdb_test "print alignof(void)" " = $expected" 189