diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 13 | ||||
-rw-r--r-- | gdb/NEWS | 3 | ||||
-rw-r--r-- | gdb/c-exp.y | 8 | ||||
-rw-r--r-- | gdb/c-lang.c | 1 | ||||
-rw-r--r-- | gdb/eval.c | 13 | ||||
-rw-r--r-- | gdb/expprint.c | 1 | ||||
-rw-r--r-- | gdb/std-operator.def | 1 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/align.exp | 109 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/align.exp | 174 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-align.exp | 83 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 30 |
12 files changed, 444 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 320f9c2..27bf1dd 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,18 @@ 2018-04-30 Tom Tromey <tom@tromey.com> + PR exp/17095: + * NEWS: Update. + * std-operator.def (UNOP_ALIGNOF): New operator. + * expprint.c (dump_subexp_body_standard) <case UNOP_ALIGNOF>: + New. + * eval.c (evaluate_subexp_standard) <case UNOP_ALIGNOF>: New. + * c-lang.c (c_op_print_tab): Add alignof. + * c-exp.y (ALIGNOF): New token. + (exp): Add "ALIGNOF" production. + (ident_tokens): Add _Alignof and alignof. + +2018-04-30 Tom Tromey <tom@tromey.com> + * i386-tdep.c (i386_type_align): New function. (i386_gdbarch_init): Update. * gdbarch.sh (type_align): New method. @@ -9,6 +9,9 @@ * 'info proc' now works on running processes on FreeBSD systems and core files created on FreeBSD systems. +* C expressions can now use _Alignof, and C++ expressions can now use + alignof. + * New commands set debug fbsd-nat diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 9e2f808..3cee544 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -173,7 +173,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value); %token <ssym> NAME_OR_INT %token OPERATOR -%token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON +%token STRUCT CLASS UNION ENUM SIZEOF ALIGNOF UNSIGNED COLONCOLON %token TEMPLATE %token ERROR %token NEW DELETE @@ -307,6 +307,10 @@ exp : SIZEOF exp %prec UNARY { write_exp_elt_opcode (pstate, UNOP_SIZEOF); } ; +exp : ALIGNOF '(' type_exp ')' %prec UNARY + { write_exp_elt_opcode (pstate, UNOP_ALIGNOF); } + ; + exp : exp ARROW name { write_exp_elt_opcode (pstate, STRUCTOP_PTR); write_exp_string (pstate, $3); @@ -2329,6 +2333,8 @@ static const struct token ident_tokens[] = {"struct", STRUCT, OP_NULL, 0}, {"signed", SIGNED_KEYWORD, OP_NULL, 0}, {"sizeof", SIZEOF, OP_NULL, 0}, + {"_Alignof", ALIGNOF, OP_NULL, 0}, + {"alignof", ALIGNOF, OP_NULL, FLAG_CXX}, {"double", DOUBLE_KEYWORD, OP_NULL, 0}, {"false", FALSEKEYWORD, OP_NULL, FLAG_CXX}, {"class", CLASS, OP_NULL, FLAG_CXX}, diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 658c7f7..15e633f 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -751,6 +751,7 @@ const struct op_print c_op_print_tab[] = {"*", UNOP_IND, PREC_PREFIX, 0}, {"&", UNOP_ADDR, PREC_PREFIX, 0}, {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0}, + {"alignof ", UNOP_ALIGNOF, PREC_PREFIX, 0}, {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0}, {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}, {NULL, OP_NULL, PREC_PREFIX, 0} @@ -2667,6 +2667,19 @@ evaluate_subexp_standard (struct type *expect_type, } return evaluate_subexp_for_sizeof (exp, pos, noside); + case UNOP_ALIGNOF: + { + struct type *type + = value_type (evaluate_subexp (NULL_TYPE, exp, pos, + EVAL_AVOID_SIDE_EFFECTS)); + /* FIXME: This should be size_t. */ + struct type *size_type = builtin_type (exp->gdbarch)->builtin_int; + ULONGEST align = type_align (type); + if (align == 0) + error (_("could not determine alignment of type")); + return value_from_longest (size_type, align); + } + case UNOP_CAST: (*pos) += 2; type = exp->elts[pc + 1].type; diff --git a/gdb/expprint.c b/gdb/expprint.c index 047ec11..70d355d 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -850,6 +850,7 @@ dump_subexp_body_standard (struct expression *exp, case UNOP_PREDECREMENT: case UNOP_POSTDECREMENT: case UNOP_SIZEOF: + case UNOP_ALIGNOF: case UNOP_PLUS: case UNOP_CAP: case UNOP_CHR: diff --git a/gdb/std-operator.def b/gdb/std-operator.def index 87bb518..1297c1e 100644 --- a/gdb/std-operator.def +++ b/gdb/std-operator.def @@ -234,6 +234,7 @@ OP (UNOP_POSTINCREMENT) /* ++ after an expression */ OP (UNOP_PREDECREMENT) /* -- before an expression */ OP (UNOP_POSTDECREMENT) /* -- after an expression */ OP (UNOP_SIZEOF) /* Unary sizeof (followed by expression) */ +OP (UNOP_ALIGNOF) /* Unary alignof (followed by expression) */ OP (UNOP_PLUS) /* Unary plus */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 22cf4ff..e8b55aa 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2018-04-30 Tom Tromey <tom@tromey.com> + + PR exp/17095: + * gdb.dwarf2/dw2-align.exp: New file. + * gdb.cp/align.exp: New file. + * gdb.base/align.exp: New file. + * lib/gdb.exp (gdb_int128_helper): New proc. + (has_int128_c, has_int128_cxx): New caching procs. + 2018-04-27 Tom Tromey <tom@tromey.com> PR rust/22545: diff --git a/gdb/testsuite/gdb.base/align.exp b/gdb/testsuite/gdb.base/align.exp new file mode 100644 index 0000000..dfe5372 --- /dev/null +++ b/gdb/testsuite/gdb.base/align.exp @@ -0,0 +1,109 @@ +# Copyright 2018 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 C11 _Alignof works in gdb, and that it agrees with +# the compiler. + +# 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} +} + +if {[has_int128_c]} { + # 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.c] +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);" + +# 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;" + 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});" + } +} + +# Epilogue. +puts $outfile { + int main() { + return 0; + } +} + +close $outfile + +standard_testfile $filename + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} { + return -1 +} + +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" diff --git a/gdb/testsuite/gdb.cp/align.exp b/gdb/testsuite/gdb.cp/align.exp new file mode 100644 index 0000000..7d5955e --- /dev/null +++ b/gdb/testsuite/gdb.cp/align.exp @@ -0,0 +1,174 @@ +# Copyright 2018 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]); + + unsigned a_void = alignof (void); + + 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" +set expected [get_integer_valueof a_void 0] +gdb_test "print alignof(void)" " = $expected" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-align.exp b/gdb/testsuite/gdb.dwarf2/dw2-align.exp new file mode 100644 index 0000000..2c2faf7 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-align.exp @@ -0,0 +1,83 @@ +# Copyright 2018 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/>. +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +standard_testfile main.c align-dw.S + +# Make some DWARF for the test. + +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + global srcdir subdir srcfile + + cu {} { + DW_TAG_compile_unit { + {DW_AT_language @DW_LANG_C_plus_plus} + {DW_AT_name dw2-align.c} + {DW_AT_comp_dir /tmp} + } { + declare_labels itype ptype + + itype: DW_TAG_base_type { + {DW_AT_byte_size 4 DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_name int_4096} + {DW_AT_alignment 4096 DW_FORM_sdata} + } + + ptype: DW_TAG_pointer_type { + {DW_AT_byte_size 8 DW_FORM_sdata} + {DW_AT_type :$itype} + {DW_AT_alignment 4096 DW_FORM_sdata} + } + + DW_TAG_typedef { + {DW_AT_name ptr_4096} + {DW_AT_type :$ptype} + } + + DW_TAG_structure_type { + {DW_AT_name "struct_4096"} + {DW_AT_byte_size 4096 DW_FORM_sdata} + {DW_AT_alignment 4096 DW_FORM_udata} + } { + member { + {name a} + {type :$itype} + {data_member_location 0 data1} + } + } + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +gdb_test_no_output "set lang c++" +gdb_test "print alignof(int_4096)" " = 4096" +gdb_test "print alignof(ptr_4096)" " = 4096" +gdb_test "print alignof(struct_4096)" " = 4096" diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 4d48f5e..0f05d04 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -3003,6 +3003,36 @@ gdb_caching_proc skip_btrace_pt_tests { return $skip_btrace_tests } +# A helper that compiles a test case to see if __int128 is supported. +proc gdb_int128_helper {lang} { + set src [standard_temp_file i128[pid].c] + set obj [standard_temp_file i128[pid].o] + + verbose -log "checking $lang for __int128" + gdb_produce_source $src { + __int128 x; + int main() { return 0; } + } + + set lines [gdb_compile $src $obj object [list nowarnings quiet $lang]] + file delete $src + file delete $obj + + set result [expr {!![string match "" $lines]}] + verbose -log "__int128 for $lang result = $result" + return $result +} + +# Return true if the C compiler understands the __int128 type. +gdb_caching_proc has_int128_c { + return [gdb_int128_helper c] +} + +# Return true if the C++ compiler understands the __int128 type. +gdb_caching_proc has_int128_cxx { + return [gdb_int128_helper c++] +} + # Return whether we should skip tests for showing inlined functions in # backtraces. Requires get_compiler_info and get_debug_format. |