# 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 . # 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 struct align_pair { T one; U two; }; template 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"