| # Copyright 2018-2021 Free Software Foundation, Inc. | 
 |  | 
 | # 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, see <http://www.gnu.org/licenses/>. | 
 |  | 
 | # This file is part of the gdb testsuite | 
 |  | 
 | # This tests that C++ alignof works in gdb, and that it agrees with | 
 | # the compiler. | 
 |  | 
 | if {[skip_cplus_tests]} { continue } | 
 |  | 
 | # The types we're going to test. | 
 |  | 
 | set typelist { | 
 |     char {unsigned char} | 
 |     short {unsigned short} | 
 |     int {unsigned int} | 
 |     long {unsigned long} | 
 |     {long long} {unsigned long long} | 
 |     float | 
 |     double {long double} | 
 |     empty | 
 |     bigenum | 
 |     vstruct | 
 |     bfstruct | 
 |     arrstruct | 
 |     derived | 
 |     derived2 | 
 | } | 
 |  | 
 | if {[has_int128_cxx]} { | 
 |     # Note we don't check "unsigned __int128" yet because at least gcc | 
 |     # canonicalizes the name to "__int128 unsigned", and there isn't a | 
 |     # c-exp.y production for this. | 
 |     # https://sourceware.org/bugzilla/show_bug.cgi?id=20991 | 
 |     lappend typelist __int128 | 
 | } | 
 |  | 
 | # Create the test file. | 
 |  | 
 | set filename [standard_output_file align.cc] | 
 | set outfile [open $filename w] | 
 |  | 
 | # Prologue. | 
 | puts $outfile { | 
 |     template<typename T, typename U> | 
 |     struct align_pair | 
 |     { | 
 | 	T one; | 
 | 	U two; | 
 |     }; | 
 |  | 
 |     template<typename T, typename U> | 
 |     struct align_union | 
 |     { | 
 | 	T one; | 
 | 	U two; | 
 |     }; | 
 |  | 
 |     enum bigenum { VALUE = 0xffffffffull }; | 
 |  | 
 |     struct empty { }; | 
 |  | 
 |     struct vstruct { virtual ~vstruct() {}  char c; }; | 
 |  | 
 |     struct bfstruct { unsigned b : 3; }; | 
 |  | 
 |     struct arrstruct { short fld[7]; }; | 
 |  | 
 |     unsigned a_int3 = alignof (int[3]); | 
 |  | 
 | #if !defined (__clang__) | 
 |     unsigned a_void = alignof (void); | 
 | #endif | 
 |  | 
 |     struct base { char c; }; | 
 |     struct derived : public virtual base { int i; }; | 
 |  | 
 |     struct b2 : public virtual base { char d; }; | 
 |     struct derived2 : public b2, derived { char e; }; | 
 | } | 
 |  | 
 | # First emit single items. | 
 | foreach type $typelist { | 
 |     set utype [join [split $type] _] | 
 |     puts $outfile "$type item_$utype;" | 
 |     puts $outfile "unsigned a_$utype\n  = alignof ($type);" | 
 |     puts $outfile "typedef $type t_$utype;" | 
 |     puts $outfile "t_$utype item_t_$utype;" | 
 | } | 
 |  | 
 | # Now emit all pairs. | 
 | foreach type $typelist { | 
 |     set utype [join [split $type] _] | 
 |     foreach inner $typelist { | 
 | 	set uinner [join [split $inner] _] | 
 | 	puts $outfile "align_pair<$type, $inner> item_${utype}_x_${uinner};" | 
 | 	puts $outfile "unsigned a_${utype}_x_${uinner}" | 
 | 	puts $outfile "  = alignof (align_pair<$type, $inner>);" | 
 |  | 
 | 	puts $outfile "align_union<$type, $inner> item_${utype}_u_${uinner};" | 
 | 	puts $outfile "unsigned a_${utype}_u_${uinner}" | 
 | 	puts $outfile "  = alignof (align_union<$type, $inner>);" | 
 |     } | 
 | } | 
 |  | 
 | # Epilogue. | 
 | puts $outfile { | 
 |     int main() { | 
 | 	return 0; | 
 |     } | 
 | } | 
 |  | 
 | close $outfile | 
 |  | 
 | standard_testfile $filename | 
 |  | 
 | if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ | 
 | 	 {debug nowarnings c++ additional_flags=-std=c++11}]} { | 
 |     return -1 | 
 | } | 
 |  | 
 | if {![runto_main]} { | 
 |     perror "test suppressed" | 
 |     return | 
 | } | 
 |  | 
 | proc maybe_xfail {type} { | 
 |     # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 | 
 |     # The g++ implementation of alignof is changing to match C11. | 
 |     if {[is_x86_like_target] | 
 | 	&& [test_compiler_info {gcc-[0-8]-*}] | 
 | 	&& ($type == "double" || $type == "long long" | 
 | 	    || $type == "unsigned long long")} { | 
 | 	setup_xfail *-*-* | 
 |     } | 
 | } | 
 |  | 
 | foreach type $typelist { | 
 |     set utype [join [split $type] _] | 
 |     set expected [get_integer_valueof a_$utype 0] | 
 |  | 
 |     maybe_xfail $type | 
 |     gdb_test "print alignof($type)" " = $expected" | 
 |  | 
 |     maybe_xfail $type | 
 |     gdb_test "print alignof(t_$utype)" " = $expected" | 
 |  | 
 |     maybe_xfail $type | 
 |     gdb_test "print alignof(typeof(item_$utype))" " = $expected" | 
 |  | 
 |     foreach inner $typelist { | 
 | 	set uinner [join [split $inner] _] | 
 | 	set expected [get_integer_valueof a_${utype}_x_${uinner} 0] | 
 | 	gdb_test "print alignof(align_pair<${type},${inner}>)" " = $expected" | 
 |  | 
 | 	set expected [get_integer_valueof a_${utype}_u_${uinner} 0] | 
 | 	gdb_test "print alignof(align_union<${type},${inner}>)" " = $expected" | 
 |     } | 
 | } | 
 |  | 
 | set expected [get_integer_valueof a_int3 0] | 
 | gdb_test "print alignof(int\[3\])" " = $expected" | 
 |  | 
 | # As an extension, GCC allows void pointer arithmetic, with | 
 | # sizeof(void) and alignof(void) both 1.  This test checks | 
 | # GDB's support of GCC's extension. | 
 | if [test_compiler_info clang*] { | 
 |     # Clang doesn't support GCC's extension. | 
 |     set expected 1 | 
 | } else { | 
 |     set expected [get_integer_valueof a_void 0] | 
 | } | 
 | gdb_test "print alignof(void)" " = $expected" |