From patchwork Fri Feb 22 22:29:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 31567 Received: (qmail 109683 invoked by alias); 22 Feb 2019 22:30:37 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 109092 invoked by uid 89); 22 Feb 2019 22:30:25 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=unavailable version=3.3.2 spammy=epilogue X-HELO: mail-wm1-f54.google.com Received: from mail-wm1-f54.google.com (HELO mail-wm1-f54.google.com) (209.85.128.54) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 22 Feb 2019 22:30:04 +0000 Received: by mail-wm1-f54.google.com with SMTP id n19so3286467wmi.1 for ; Fri, 22 Feb 2019 14:30:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=1V36g55UhdodLTSAH2Bg9eRa+gxWKZerICRd5WPtpbw=; b=dziKYPamhU6DhS6xaxXtrKzMACP0fgU5ct2LyN/dTwl80Bf5thwGzPz/3V0D9Q4nBU mZTTGz/8CZstQFPEnmQPBxEkPAofMwp1isGHIYuE/LkwOJBgQjgKkTjgKJFSwLxytCve uImk2lZirE6bQlSZIQ94YuNyu1X5q8xNuXcMgKscqscej201LUwRxIL7kbqoL27gDcS5 8VRlSil7BglxliUpl7wpJYTs7zQ7Xad14VjHikhga2kJdh9oTKNsL2Er27QdjgmVYfNf Rxwu9z1smTSya93YV7qzH8/qWH8fRfp0Q7nE8g/Jlv98rZ+YfXKyDjDtxtwV8v7AApxr GbHg== Return-Path: Received: from localhost ([94.185.164.146]) by smtp.gmail.com with ESMTPSA id v20sm1943349wmj.2.2019.02.22.14.30.01 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 22 Feb 2019 14:30:01 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Tom Tromey , Andrew Burgess Subject: [PATCH 2/2] gdb: Handle alignment for C++ structures with static members Date: Fri, 22 Feb 2019 22:29:54 +0000 Message-Id: In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes 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. --- gdb/ChangeLog | 5 ++ gdb/gdbtypes.c | 17 ++-- gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.base/align.exp | 180 +++++++++++++++++++++++++++------------ 4 files changed, 147 insertions(+), 60 deletions(-) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 63dec3c8b7d..db9a78a80a6 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 (TYPE_FIELD_LOC_KIND (type, i) == FIELD_LOC_KIND_BITPOS) { - /* 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/gdb.base/align.exp b/gdb/testsuite/gdb.base/align.exp index e7dcf2a5480..558625d1b3e 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 + + # Create the test file. -set filename [standard_output_file align.c] -set outfile [open $filename w] + if { $lang == "c++" } { + set suffix "cpp" + set align_func "alignof" + } else { + set suffix "c" + set align_func "_Alignof" + } -# 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);" + set filename [standard_output_file "$lang/align.$suffix"] + set outfile [open $filename w] -# First emit single items. -foreach type $typelist { - set utype [join [split $type] _] - if {$type != $utype} { - puts $outfile "typedef $type $utype;" + # 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);" } - puts $outfile "$type item_$utype;" - puts $outfile "unsigned a_$utype\n = _Alignof ($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 " = _Alignof (struct align_pair_${joined});" + # 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] _] } -} -# Epilogue. -puts $outfile { - int main() { - return 0; + # 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});" + } + } } -} -close $outfile + # Epilogue. + puts $outfile { + int main() { + return 0; + } + } -standard_testfile $filename + close $outfile -if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} { - return -1 + return $filename } -if {![runto_main]} { - perror "test suppressed" - return -} +# 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] -foreach type $typelist { - set utype [join [split $type] _] - set expected [get_integer_valueof a_$utype 0] - gdb_test "print _Alignof($type)" " = $expected" + 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 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" + 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" } } -set expected [get_integer_valueof a_void 0] -gdb_test "print _Alignof(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 +}