aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog13
-rw-r--r--gdb/NEWS3
-rw-r--r--gdb/c-exp.y8
-rw-r--r--gdb/c-lang.c1
-rw-r--r--gdb/eval.c13
-rw-r--r--gdb/expprint.c1
-rw-r--r--gdb/std-operator.def1
-rw-r--r--gdb/testsuite/ChangeLog9
-rw-r--r--gdb/testsuite/gdb.base/align.exp109
-rw-r--r--gdb/testsuite/gdb.cp/align.exp174
-rw-r--r--gdb/testsuite/gdb.dwarf2/dw2-align.exp83
-rw-r--r--gdb/testsuite/lib/gdb.exp30
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.
diff --git a/gdb/NEWS b/gdb/NEWS
index 63fe30d..6631b53 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -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}
diff --git a/gdb/eval.c b/gdb/eval.c
index ad66f7c..2fdfdf9 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -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.