gdb: Handle alignment for C++ structures with static members
In 'type_align' when computing the alignment of a structure we should not consider the alignment of static structure members, these are usually stored outside of the structure and therefore don't have any impact on the structures alignment requirements. I've extended the existing alignment calculating test to compile in both C and C++ now so that we can create structures with static members. gdb/ChangeLog: * gdbtypes.c (type_align): Don't consider static members when computing structure alignment. gdb/testsuite/ChangeLog: * gdb.base/align.exp: Extend to compile in both C and C++, and add tests for structs with static members.
This commit is contained in:
parent
5561fc304f
commit
bf9a735e23
|
@ -1,3 +1,8 @@
|
|||
2019-02-27 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* gdbtypes.c (type_align): Don't consider static members when
|
||||
computing structure alignment.
|
||||
|
||||
2019-02-27 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* arc-tdep.c (arc_type_align): Provide alignment for basic types,
|
||||
|
|
|
@ -3038,6 +3038,8 @@ type_align (struct type *type)
|
|||
break;
|
||||
}
|
||||
for (unsigned i = 0; i < TYPE_NFIELDS (type); ++i)
|
||||
{
|
||||
if (!field_is_static (&TYPE_FIELD (type, i)))
|
||||
{
|
||||
ULONGEST f_align = type_align (TYPE_FIELD_TYPE (type, i));
|
||||
if (f_align == 0)
|
||||
|
@ -3050,6 +3052,7 @@ type_align (struct type *type)
|
|||
align = f_align;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_SET:
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2019-02-27 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* gdb.base/align.exp: Extend to compile in both C and C++, and add
|
||||
tests for structs with static members.
|
||||
|
||||
2019-02-26 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* gdb.python/py-value.exp (test_value_from_buffer): Check for
|
||||
|
|
|
@ -15,8 +15,15 @@
|
|||
|
||||
# This file is part of the gdb testsuite
|
||||
|
||||
# This tests that C11 _Alignof works in gdb, and that it agrees with
|
||||
# the compiler.
|
||||
# This tests that C11 _Alignof and C++11 alignof works in gdb, and
|
||||
# that it agrees with the compiler.
|
||||
|
||||
# Only test C++ if we are able. Always use C.
|
||||
if { [skip_cplus_tests] || [get_compiler_info "c++"] } {
|
||||
set lang {c}
|
||||
} else {
|
||||
set lang {c c++}
|
||||
}
|
||||
|
||||
# The types we're going to test.
|
||||
|
||||
|
@ -38,15 +45,34 @@ if {[has_int128_c]} {
|
|||
lappend typelist __int128
|
||||
}
|
||||
|
||||
# Build source file for testing alignment handling of language LANG.
|
||||
# Returns the name of the newly created source file.
|
||||
proc prepare_test_source_file { lang } {
|
||||
global typelist
|
||||
|
||||
# Create the test file.
|
||||
|
||||
set filename [standard_output_file align.c]
|
||||
if { $lang == "c++" } {
|
||||
set suffix "cpp"
|
||||
set align_func "alignof"
|
||||
} else {
|
||||
set suffix "c"
|
||||
set align_func "_Alignof"
|
||||
}
|
||||
|
||||
set filename [standard_output_file "$lang/align.$suffix"]
|
||||
set outfile [open $filename w]
|
||||
|
||||
# Prologue.
|
||||
puts -nonewline $outfile "#define DEF(T,U) struct align_pair_ ## T ## _x_ ## U "
|
||||
puts $outfile "{ T one; U two; }"
|
||||
puts $outfile "unsigned a_void = _Alignof(void);"
|
||||
if { $lang == "c++" } {
|
||||
puts -nonewline $outfile "#define DEF_WITH_STATIC(T,U) struct align_pair_static_ ## T ## _x_ ## U "
|
||||
puts $outfile "{ static T one; U two; }"
|
||||
}
|
||||
if { $lang == "c" } {
|
||||
puts $outfile "unsigned a_void = ${align_func} (void);"
|
||||
}
|
||||
|
||||
# First emit single items.
|
||||
foreach type $typelist {
|
||||
|
@ -55,7 +81,9 @@ foreach type $typelist {
|
|||
puts $outfile "typedef $type $utype;"
|
||||
}
|
||||
puts $outfile "$type item_$utype;"
|
||||
puts $outfile "unsigned a_$utype\n = _Alignof ($type);"
|
||||
if { $lang == "c" } {
|
||||
puts $outfile "unsigned a_$utype\n = ${align_func} ($type);"
|
||||
}
|
||||
set utype [join [split $type] _]
|
||||
}
|
||||
|
||||
|
@ -68,7 +96,15 @@ foreach type $typelist {
|
|||
set joined "${utype}_x_${uinner}"
|
||||
puts $outfile "struct align_pair_$joined item_${joined};"
|
||||
puts $outfile "unsigned a_${joined}"
|
||||
puts $outfile " = _Alignof (struct align_pair_${joined});"
|
||||
puts $outfile " = ${align_func} (struct align_pair_${joined});"
|
||||
|
||||
if { $lang == "c++" } {
|
||||
puts $outfile "DEF_WITH_STATIC ($utype, $uinner);"
|
||||
set joined "${utype}_x_${uinner}"
|
||||
puts $outfile "struct align_pair_static_$joined item_static_${joined};"
|
||||
puts $outfile "unsigned a_static_${joined}"
|
||||
puts $outfile " = ${align_func} (struct align_pair_static_${joined});"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,9 +117,18 @@ puts $outfile {
|
|||
|
||||
close $outfile
|
||||
|
||||
standard_testfile $filename
|
||||
return $filename
|
||||
}
|
||||
|
||||
if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} {
|
||||
# Run the alignment test for the language LANG.
|
||||
proc run_alignment_test { lang } {
|
||||
global testfile srcfile typelist
|
||||
global subdir
|
||||
|
||||
set filename [prepare_test_source_file $lang]
|
||||
|
||||
standard_testfile $filename
|
||||
if {[prepare_for_testing "failed to prepare" "$lang/$testfile" $srcfile {debug}]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
|
@ -92,18 +137,47 @@ if {![runto_main]} {
|
|||
return
|
||||
}
|
||||
|
||||
if { $lang == "c++" } {
|
||||
set align_func "alignof"
|
||||
} else {
|
||||
set align_func "_Alignof"
|
||||
}
|
||||
|
||||
foreach type $typelist {
|
||||
set utype [join [split $type] _]
|
||||
if { $lang == "c" } {
|
||||
set expected [get_integer_valueof a_$utype 0]
|
||||
gdb_test "print _Alignof($type)" " = $expected"
|
||||
gdb_test "print ${align_func}($type)" " = $expected"
|
||||
}
|
||||
|
||||
foreach inner $typelist {
|
||||
set uinner [join [split $inner] _]
|
||||
set expected [get_integer_valueof a_${utype}_x_${uinner} 0]
|
||||
gdb_test "print _Alignof(struct align_pair_${utype}_x_${uinner})" \
|
||||
gdb_test "print ${align_func}(struct align_pair_${utype}_x_${uinner})" \
|
||||
" = $expected"
|
||||
|
||||
if { $lang == "c++" } {
|
||||
set expected [get_integer_valueof a_static_${utype}_x_${uinner} 0]
|
||||
gdb_test "print ${align_func}(struct align_pair_static_${utype}_x_${uinner})" \
|
||||
" = $expected"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if { $lang == "c" } {
|
||||
set expected [get_integer_valueof a_void 0]
|
||||
gdb_test "print _Alignof(void)" " = $expected"
|
||||
gdb_test "print ${align_func}(void)" " = $expected"
|
||||
}
|
||||
}
|
||||
|
||||
# Create nested 'c' and 'c++' directories within this tests directory.
|
||||
foreach l $lang {
|
||||
set dir "$l"
|
||||
remote_exec host "rm -rf [standard_output_file ${dir}]"
|
||||
remote_exec host "mkdir -p [standard_output_file ${dir}]"
|
||||
}
|
||||
|
||||
# Now run the test for each language.
|
||||
foreach_with_prefix l $lang {
|
||||
run_alignment_test $l
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue