diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 07f3c478b2..ae9a68fec0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2019-02-27 Andrew Burgess + + * gdbtypes.c (type_align): Don't consider static members when + computing structure alignment. + 2019-02-27 Andrew Burgess * arc-tdep.c (arc_type_align): Provide alignment for basic types, diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 63dec3c8b7..b5f269241c 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -3039,15 +3039,18 @@ type_align (struct type *type) } for (unsigned i = 0; i < TYPE_NFIELDS (type); ++i) { - ULONGEST f_align = type_align (TYPE_FIELD_TYPE (type, i)); - if (f_align == 0) + if (!field_is_static (&TYPE_FIELD (type, i))) { - /* Don't pretend we know something we don't. */ - align = 0; - break; + ULONGEST f_align = type_align (TYPE_FIELD_TYPE (type, i)); + if (f_align == 0) + { + /* Don't pretend we know something we don't. */ + align = 0; + break; + } + if (f_align > align) + align = f_align; } - if (f_align > align) - align = f_align; } } break; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 693fc150f7..afe39de202 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-02-27 Andrew Burgess + + * 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 * gdb.python/py-value.exp (test_value_from_buffer): Check for diff --git a/gdb/testsuite/gdb.base/align.exp b/gdb/testsuite/gdb.base/align.exp index e7dcf2a548..558625d1b3 100644 --- a/gdb/testsuite/gdb.base/align.exp +++ b/gdb/testsuite/gdb.base/align.exp @@ -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,72 +45,139 @@ if {[has_int128_c]} { lappend typelist __int128 } -# Create the test file. +# 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 -set filename [standard_output_file align.c] -set outfile [open $filename w] + # Create the test file. -# 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);" - -# First emit single items. -foreach type $typelist { - set utype [join [split $type] _] - if {$type != $utype} { - puts $outfile "typedef $type $utype;" + if { $lang == "c++" } { + set suffix "cpp" + set align_func "alignof" + } else { + set suffix "c" + set align_func "_Alignof" } - puts $outfile "$type item_$utype;" - puts $outfile "unsigned a_$utype\n = _Alignof ($type);" - set utype [join [split $type] _] + + 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; }" + 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 { + set utype [join [split $type] _] + if {$type != $utype} { + puts $outfile "typedef $type $utype;" + } + puts $outfile "$type item_$utype;" + if { $lang == "c" } { + puts $outfile "unsigned a_$utype\n = ${align_func} ($type);" + } + set utype [join [split $type] _] + } + + # Now emit all pairs. + foreach type $typelist { + set utype [join [split $type] _] + foreach inner $typelist { + set uinner [join [split $inner] _] + puts $outfile "DEF ($utype, $uinner);" + set joined "${utype}_x_${uinner}" + puts $outfile "struct align_pair_$joined item_${joined};" + puts $outfile "unsigned a_${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});" + } + } + } + + # Epilogue. + puts $outfile { + int main() { + return 0; + } + } + + close $outfile + + return $filename } -# Now emit all pairs. -foreach type $typelist { - set utype [join [split $type] _] - foreach inner $typelist { - set uinner [join [split $inner] _] - puts $outfile "DEF ($utype, $uinner);" - 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});" +# 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 + } + + if {![runto_main]} { + perror "test suppressed" + 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 ${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 ${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 ${align_func}(void)" " = $expected" } } -# Epilogue. -puts $outfile { - int main() { - return 0; - } +# 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}]" } -close $outfile - -standard_testfile $filename - -if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} { - return -1 +# Now run the test for each language. +foreach_with_prefix l $lang { + run_alignment_test $l } - -if {![runto_main]} { - perror "test suppressed" - return -} - -foreach type $typelist { - set utype [join [split $type] _] - set expected [get_integer_valueof a_$utype 0] - gdb_test "print _Alignof($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})" \ - " = $expected" - } -} - -set expected [get_integer_valueof a_void 0] -gdb_test "print _Alignof(void)" " = $expected"