1# Copyright 2018-2020 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 (__clang__) 84 unsigned a_void = alignof (void); 85#endif 86 87 struct base { char c; }; 88 struct derived : public virtual base { int i; }; 89 90 struct b2 : public virtual base { char d; }; 91 struct derived2 : public b2, derived { char e; }; 92} 93 94# First emit single items. 95foreach type $typelist { 96 set utype [join [split $type] _] 97 puts $outfile "$type item_$utype;" 98 puts $outfile "unsigned a_$utype\n = alignof ($type);" 99 puts $outfile "typedef $type t_$utype;" 100 puts $outfile "t_$utype item_t_$utype;" 101} 102 103# Now emit all pairs. 104foreach type $typelist { 105 set utype [join [split $type] _] 106 foreach inner $typelist { 107 set uinner [join [split $inner] _] 108 puts $outfile "align_pair<$type, $inner> item_${utype}_x_${uinner};" 109 puts $outfile "unsigned a_${utype}_x_${uinner}" 110 puts $outfile " = alignof (align_pair<$type, $inner>);" 111 112 puts $outfile "align_union<$type, $inner> item_${utype}_u_${uinner};" 113 puts $outfile "unsigned a_${utype}_u_${uinner}" 114 puts $outfile " = alignof (align_union<$type, $inner>);" 115 } 116} 117 118# Epilogue. 119puts $outfile { 120 int main() { 121 return 0; 122 } 123} 124 125close $outfile 126 127standard_testfile $filename 128 129if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ 130 {debug nowarnings c++ additional_flags=-std=c++11}]} { 131 return -1 132} 133 134if {![runto_main]} { 135 perror "test suppressed" 136 return 137} 138 139proc maybe_xfail {type} { 140 # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 141 # The g++ implementation of alignof is changing to match C11. 142 if {[is_x86_like_target] 143 && [test_compiler_info {gcc-[0-8]-*}] 144 && ($type == "double" || $type == "long long" 145 || $type == "unsigned long long")} { 146 setup_xfail *-*-* 147 } 148} 149 150foreach type $typelist { 151 set utype [join [split $type] _] 152 set expected [get_integer_valueof a_$utype 0] 153 154 maybe_xfail $type 155 gdb_test "print alignof($type)" " = $expected" 156 157 maybe_xfail $type 158 gdb_test "print alignof(t_$utype)" " = $expected" 159 160 maybe_xfail $type 161 gdb_test "print alignof(typeof(item_$utype))" " = $expected" 162 163 foreach inner $typelist { 164 set uinner [join [split $inner] _] 165 set expected [get_integer_valueof a_${utype}_x_${uinner} 0] 166 gdb_test "print alignof(align_pair<${type},${inner}>)" " = $expected" 167 168 set expected [get_integer_valueof a_${utype}_u_${uinner} 0] 169 gdb_test "print alignof(align_union<${type},${inner}>)" " = $expected" 170 } 171} 172 173set expected [get_integer_valueof a_int3 0] 174gdb_test "print alignof(int\[3\])" " = $expected" 175 176# As an extension, GCC allows void pointer arithmetic, with 177# sizeof(void) and alignof(void) both 1. This test checks 178# GDB's support of GCC's extension. 179if [test_compiler_info clang*] { 180 # Clang doesn't support GCC's extension. 181 set expected 1 182} else { 183 set expected [get_integer_valueof a_void 0] 184} 185gdb_test "print alignof(void)" " = $expected" 186