public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFA v2 5/6] Remove rust_type_alignment
  2018-04-27 14:01 [RFA v2 0/6] Type alignment Tom Tromey
@ 2018-04-27 14:01 ` Tom Tromey
  2018-04-27 14:01 ` [RFA v2 4/6] Expose type alignment on gdb.Type Tom Tromey
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 14:01 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

rust_type_alignment is not needed now that gdb has type alignment
code.  So, this removes it.

2018-04-27  Tom Tromey  <tom@tromey.com>

	* rust-lang.c (rust_type_alignment): Remove.
	(rust_composite_type): Use type_align.
---
 gdb/ChangeLog   |  5 +++++
 gdb/rust-lang.c | 43 +------------------------------------------
 2 files changed, 6 insertions(+), 42 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4e1f52dbdf..8aa0fc655e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2018-04-27  Tom Tromey  <tom@tromey.com>
+
+	* rust-lang.c (rust_type_alignment): Remove.
+	(rust_composite_type): Use type_align.
+
 2018-04-27  Tom Tromey  <tom@tromey.com>
 
 	* NEWS: Mention Type.align.
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index cf8a15ee43..74e86d7008 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -851,47 +851,6 @@ rust_print_type (struct type *type, const char *varstring,
 
 \f
 
-/* Compute the alignment of the type T.  */
-
-static int
-rust_type_alignment (struct type *t)
-{
-  t = check_typedef (t);
-  switch (TYPE_CODE (t))
-    {
-    default:
-      error (_("Could not compute alignment of type"));
-
-    case TYPE_CODE_PTR:
-    case TYPE_CODE_ENUM:
-    case TYPE_CODE_INT:
-    case TYPE_CODE_FLT:
-    case TYPE_CODE_REF:
-    case TYPE_CODE_CHAR:
-    case TYPE_CODE_BOOL:
-      return TYPE_LENGTH (t);
-
-    case TYPE_CODE_ARRAY:
-    case TYPE_CODE_COMPLEX:
-      return rust_type_alignment (TYPE_TARGET_TYPE (t));
-
-    case TYPE_CODE_STRUCT:
-    case TYPE_CODE_UNION:
-      {
-	int i;
-	int align = 1;
-
-	for (i = 0; i < TYPE_NFIELDS (t); ++i)
-	  {
-	    int a = rust_type_alignment (TYPE_FIELD_TYPE (t, i));
-	    if (a > align)
-	      align = a;
-	  }
-	return align;
-      }
-    }
-}
-
 /* Like arch_composite_type, but uses TYPE to decide how to allocate
    -- either on an obstack or on a gdbarch.  */
 
@@ -934,7 +893,7 @@ rust_composite_type (struct type *original,
   if (field2 != NULL)
     {
       struct field *field = &TYPE_FIELD (result, i);
-      int align = rust_type_alignment (type2);
+      unsigned align = type_align (type2);
 
       if (align != 0)
 	{
-- 
2.14.3

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFA v2 3/6] Reindent type_object_getset in py-type.c
  2018-04-27 14:01 [RFA v2 0/6] Type alignment Tom Tromey
                   ` (3 preceding siblings ...)
  2018-04-27 14:01 ` [RFA v2 2/6] Handle alignof and _Alignof Tom Tromey
@ 2018-04-27 14:01 ` Tom Tromey
  2018-04-27 18:47   ` Pedro Alves
  2018-04-27 14:01 ` [RFA v2 6/6] Remove long_long_align_bit gdbarch attribute Tom Tromey
  5 siblings, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 14:01 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

I noticed that type_object_getset was indented incorrectly.  This
fixes it.

2018-04-27  Tom Tromey  <tom@tromey.com>

	* python/py-type.c (type_object_getset): Reindent.
---
 gdb/ChangeLog        |  4 ++++
 gdb/python/py-type.c | 18 +++++++++---------
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 73eba465a1..caab3a7284 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,7 @@
+2018-04-27  Tom Tromey  <tom@tromey.com>
+
+	* python/py-type.c (type_object_getset): Reindent.
+
 2018-04-27  Tom Tromey  <tom@tromey.com>
 
 	PR exp/17095:
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 8a948eeaa6..fcd6ed5621 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -1410,15 +1410,15 @@ gdbpy_initialize_types (void)
 
 static gdb_PyGetSetDef type_object_getset[] =
 {
-  { "code", typy_get_code, NULL,
-    "The code for this type.", NULL },
-  { "name", typy_get_name, NULL,
-    "The name for this type, or None.", NULL },
-  { "sizeof", typy_get_sizeof, NULL,
-    "The size of this type, in bytes.", NULL },
-  { "tag", typy_get_tag, NULL,
-    "The tag name for this type, or None.", NULL },
-  { NULL }
+ { "code", typy_get_code, NULL,
+   "The code for this type.", NULL },
+ { "name", typy_get_name, NULL,
+   "The name for this type, or None.", NULL },
+ { "sizeof", typy_get_sizeof, NULL,
+   "The size of this type, in bytes.", NULL },
+ { "tag", typy_get_tag, NULL,
+   "The tag name for this type, or None.", NULL },
+ { NULL }
 };
 
 static PyMethodDef type_object_methods[] =
-- 
2.14.3

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFA v2 1/6] Add initial type alignment support
  2018-04-27 14:01 [RFA v2 0/6] Type alignment Tom Tromey
  2018-04-27 14:01 ` [RFA v2 5/6] Remove rust_type_alignment Tom Tromey
  2018-04-27 14:01 ` [RFA v2 4/6] Expose type alignment on gdb.Type Tom Tromey
@ 2018-04-27 14:01 ` Tom Tromey
  2018-04-27 18:46   ` Pedro Alves
  2018-04-27 14:01 ` [RFA v2 2/6] Handle alignof and _Alignof Tom Tromey
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 14:01 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This adds some basic type alignment support to gdb.  It changes struct
type to store the alignment, and updates dwarf2read.c to handle
DW_AT_alignment.  It also adds a new gdbarch method and updates
i386-tdep.c.

None of this new functionality is used anywhere yet, so tests will
wait until the next patch.

2018-04-27  Tom Tromey  <tom@tromey.com>

	* i386-tdep.c (i386_type_align): New function.
	(i386_gdbarch_init): Update.
	* gdbarch.sh (type_align): New method.
	* gdbarch.c, gdbarch.h: Rebuild.
	* arch-utils.h (default_type_align): Declare.
	* arch-utils.c (default_type_align): New function.
	* gdbtypes.h (TYPE_ALIGN_BITS): New define.
	(struct type) <align_log2>: New field.
	<instance_flags>: Now a bitfield.
	(TYPE_RAW_ALIGN): New macro.
	(type_align, type_raw_align, set_type_align): Declare.
	* gdbtypes.c (type_align, type_raw_align, set_type_align): New
	functions.
	* dwarf2read.c (quirk_rust_enum): Set type alignment.
	(get_alignment, maybe_set_alignment): New functions.
	(read_structure_type, read_enumeration_type, read_array_type)
	(read_set_type, read_tag_pointer_type, read_tag_reference_type)
	(read_subrange_type, read_base_type): Set type alignment.
---
 gdb/ChangeLog    |  21 ++++++++++
 gdb/arch-utils.c |   8 ++++
 gdb/arch-utils.h |   4 ++
 gdb/dwarf2read.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 gdb/gdbarch.c    |  23 +++++++++++
 gdb/gdbarch.h    |   6 +++
 gdb/gdbarch.sh   |   3 ++
 gdb/gdbtypes.c   | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/gdbtypes.h   |  34 +++++++++++++++-
 gdb/i386-tdep.c  |  26 ++++++++++++
 10 files changed, 359 insertions(+), 5 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index cd86be7fb3..1b5abb2f0d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,24 @@
+2018-04-27  Tom Tromey  <tom@tromey.com>
+
+	* i386-tdep.c (i386_type_align): New function.
+	(i386_gdbarch_init): Update.
+	* gdbarch.sh (type_align): New method.
+	* gdbarch.c, gdbarch.h: Rebuild.
+	* arch-utils.h (default_type_align): Declare.
+	* arch-utils.c (default_type_align): New function.
+	* gdbtypes.h (TYPE_ALIGN_BITS): New define.
+	(struct type) <align_log2>: New field.
+	<instance_flags>: Now a bitfield.
+	(TYPE_RAW_ALIGN): New macro.
+	(type_align, type_raw_align, set_type_align): Declare.
+	* gdbtypes.c (type_align, type_raw_align, set_type_align): New
+	functions.
+	* dwarf2read.c (quirk_rust_enum): Set type alignment.
+	(get_alignment, maybe_set_alignment): New functions.
+	(read_structure_type, read_enumeration_type, read_array_type)
+	(read_set_type, read_tag_pointer_type, read_tag_reference_type)
+	(read_subrange_type, read_base_type): Set type alignment.
+
 2018-04-26  Andrzej Kaczmarek  <andrzej.kaczmarek@codecoup.pl>
 
 	PR remote/9665
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index cd9bd66430..e3cce491ee 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -987,6 +987,14 @@ default_in_indirect_branch_thunk (gdbarch *gdbarch, CORE_ADDR pc)
   return false;
 }
 
+/* See arch-utils.h.  */
+
+ULONGEST
+default_type_align (struct gdbarch *gdbarch, struct type *type)
+{
+  return TYPE_LENGTH (check_typedef (type));
+}
+
 void
 _initialize_gdbarch_utils (void)
 {
diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h
index b785b24643..77ee9af2bf 100644
--- a/gdb/arch-utils.h
+++ b/gdb/arch-utils.h
@@ -267,4 +267,8 @@ extern CORE_ADDR gdbarch_skip_prologue_noexcept (gdbarch *gdbarch,
 extern bool default_in_indirect_branch_thunk (gdbarch *gdbarch,
 					      CORE_ADDR pc);
 
+/* Default implementation of gdbarch type_align method.  */
+extern ULONGEST default_type_align (struct gdbarch *gdbarch,
+				    struct type *type);
+
 #endif
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 4207e4c531..0ca055675f 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -9907,6 +9907,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       TYPE_FIELDS (union_type)
 	= (struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field));
       TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
+      set_type_align (union_type, TYPE_RAW_ALIGN (type));
 
       /* Put the discriminant must at index 0.  */
       TYPE_FIELD_TYPE (union_type, 0) = field_type;
@@ -9962,6 +9963,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       TYPE_CODE (union_type) = TYPE_CODE_UNION;
       TYPE_NFIELDS (union_type) = TYPE_NFIELDS (type);
       TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
+      set_type_align (union_type, TYPE_RAW_ALIGN (type));
       TYPE_FIELDS (union_type) = TYPE_FIELDS (type);
 
       struct type *field_type = TYPE_FIELD_TYPE (union_type, 0);
@@ -10027,6 +10029,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
       TYPE_CODE (union_type) = TYPE_CODE_UNION;
       TYPE_NFIELDS (union_type) = 1 + TYPE_NFIELDS (type);
       TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
+      set_type_align (union_type, TYPE_RAW_ALIGN (type));
       TYPE_FIELDS (union_type)
 	= (struct field *) TYPE_ZALLOC (union_type,
 					(TYPE_NFIELDS (union_type)
@@ -15578,6 +15581,82 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
   smash_to_methodptr_type (type, new_type);
 }
 
+/* If the DIE has a DW_AT_alignment attribute, return its value, doing
+   appropriate error checking and issuing complaints if there is a
+   problem.  */
+
+static ULONGEST
+get_alignment (struct dwarf2_cu *cu, struct die_info *die)
+{
+  struct attribute *attr = dwarf2_attr (die, DW_AT_alignment, cu);
+
+  if (attr == nullptr)
+    return 0;
+
+  if (!attr_form_is_constant (attr))
+    {
+      complaint (&symfile_complaints,
+		 _("DW_AT_alignment must have constant form"
+		   " - DIE at %s [in module %s]"),
+		 sect_offset_str (die->sect_off),
+		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+      return 0;
+    }
+
+  ULONGEST align;
+  if (attr->form == DW_FORM_sdata)
+    {
+      LONGEST val = DW_SND (attr);
+      if (val < 0)
+	{
+	  complaint (&symfile_complaints,
+		     _("DW_AT_alignment value must not be negative"
+		       " - DIE at %s [in module %s]"),
+		     sect_offset_str (die->sect_off),
+		     objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+	  return 0;
+	}
+      align = val;
+    }
+  else
+    align = DW_UNSND (attr);
+
+  if (align == 0)
+    {
+      complaint (&symfile_complaints,
+		 _("DW_AT_alignment value must not be zero"
+		   " - DIE at %s [in module %s]"),
+		 sect_offset_str (die->sect_off),
+		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+      return 0;
+    }
+  if ((align & (align - 1)) != 0)
+    {
+      complaint (&symfile_complaints,
+		 _("DW_AT_alignment value must be a power of 2"
+		   " - DIE at %s [in module %s]"),
+		 sect_offset_str (die->sect_off),
+		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+      return 0;
+    }
+
+  return align;
+}
+
+/* If the DIE has a DW_AT_alignment attribute, use its value to set
+   the alignment for TYPE.  */
+
+static void
+maybe_set_alignment (struct dwarf2_cu *cu, struct die_info *die,
+		     struct type *type)
+{
+  if (!set_type_align (type, get_alignment (cu, die)))
+    complaint (&symfile_complaints,
+	       _("DW_AT_alignment value too large"
+		 " - DIE at %s [in module %s]"),
+	       sect_offset_str (die->sect_off),
+	       objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+}
 
 /* Called when we find the DIE that starts a structure or union scope
    (definition) to create a type for the structure or union.  Fill in
@@ -15688,6 +15767,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_LENGTH (type) = 0;
     }
 
+  maybe_set_alignment (cu, die, type);
+
   if (producer_is_icc_lt_14 (cu) && (TYPE_LENGTH (type) == 0))
     {
       /* ICC<14 does not output the required DW_AT_declaration on
@@ -16132,6 +16213,8 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_LENGTH (type) = 0;
     }
 
+  maybe_set_alignment (cu, die, type);
+
   /* The enumeration DIE can be incomplete.  In Ada, any type can be
      declared as private in the package spec, and then defined only
      inside the package body.  Such types are known as Taft Amendment
@@ -16157,6 +16240,9 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
       TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TYPE_TARGET_TYPE (type));
       if (TYPE_LENGTH (type) == 0)
 	TYPE_LENGTH (type) = TYPE_LENGTH (TYPE_TARGET_TYPE (type));
+      if (TYPE_RAW_ALIGN (type) == 0
+	  && TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)) != 0)
+	set_type_align (type, TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)));
     }
 
   TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
@@ -16381,6 +16467,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
   if (name)
     TYPE_NAME (type) = name;
 
+  maybe_set_alignment (cu, die, type);
+
   /* Install the type in the die.  */
   set_die_type (die, type, cu);
 
@@ -16445,6 +16533,8 @@ read_set_type (struct die_info *die, struct dwarf2_cu *cu)
   if (attr)
     TYPE_LENGTH (set_type) = DW_UNSND (attr);
 
+  maybe_set_alignment (cu, die, set_type);
+
   return set_die_type (die, set_type, cu);
 }
 
@@ -16816,10 +16906,15 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
   else
     addr_class = DW_ADDR_none;
 
-  /* If the pointer size or address class is different than the
-     default, create a type variant marked as such and set the
-     length accordingly.  */
-  if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none)
+  ULONGEST alignment = get_alignment (cu, die);
+
+  /* If the pointer size, alignment, or address class is different
+     than the default, create a type variant marked as such and set
+     the length accordingly.  */
+  if (TYPE_LENGTH (type) != byte_size
+      || (alignment != 0 && TYPE_RAW_ALIGN (type) != 0
+	  && alignment != TYPE_RAW_ALIGN (type))
+      || addr_class != DW_ADDR_none)
     {
       if (gdbarch_address_class_type_flags_p (gdbarch))
 	{
@@ -16836,6 +16931,14 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 	  complaint (&symfile_complaints,
 		     _("invalid pointer size %d"), byte_size);
 	}
+      else if (TYPE_RAW_ALIGN (type) != alignment)
+	{
+	  complaint (&symfile_complaints,
+		     _("Invalid DW_AT_alignment"
+		       " - DIE at %s [in module %s]"),
+		     sect_offset_str (die->sect_off),
+		     objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+	}
       else
 	{
 	  /* Should we also complain about unhandled address classes?  */
@@ -16843,6 +16946,7 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   TYPE_LENGTH (type) = byte_size;
+  set_type_align (type, alignment);
   return set_die_type (die, type, cu);
 }
 
@@ -16912,6 +17016,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
     {
       TYPE_LENGTH (type) = cu_header->addr_size;
     }
+  maybe_set_alignment (cu, die, type);
   return set_die_type (die, type, cu);
 }
 
@@ -17398,6 +17503,8 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
   if (name && strcmp (name, "char") == 0)
     TYPE_NOSIGN (type) = 1;
 
+  maybe_set_alignment (cu, die, type);
+
   return set_die_type (die, type, cu);
 }
 
@@ -17660,6 +17767,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   if (attr)
     TYPE_LENGTH (range_type) = DW_UNSND (attr);
 
+  maybe_set_alignment (cu, die, range_type);
+
   set_die_type (die, range_type, cu);
 
   /* set_die_type should be already done.  */
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 1359c2fb53..dd7c89d948 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -353,6 +353,7 @@ struct gdbarch
   gdbarch_addressable_memory_unit_size_ftype *addressable_memory_unit_size;
   char ** disassembler_options;
   const disasm_options_t * valid_disassembler_options;
+  gdbarch_type_align_ftype *type_align;
 };
 
 /* Create a new ``struct gdbarch'' based on information provided by
@@ -465,6 +466,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
   gdbarch->gcc_target_options = default_gcc_target_options;
   gdbarch->gnu_triplet_regexp = default_gnu_triplet_regexp;
   gdbarch->addressable_memory_unit_size = default_addressable_memory_unit_size;
+  gdbarch->type_align = default_type_align;
   /* gdbarch_alloc() */
 
   return gdbarch;
@@ -716,6 +718,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of addressable_memory_unit_size, invalid_p == 0 */
   /* Skip verify of disassembler_options, invalid_p == 0 */
   /* Skip verify of valid_disassembler_options, invalid_p == 0 */
+  /* Skip verify of type_align, invalid_p == 0 */
   if (!log.empty ())
     internal_error (__FILE__, __LINE__,
                     _("verify_gdbarch: the following are invalid ...%s"),
@@ -1441,6 +1444,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                       "gdbarch_dump: target_desc = %s\n",
                       host_address_to_string (gdbarch->target_desc));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: type_align = <%s>\n",
+                      host_address_to_string (gdbarch->type_align));
   fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_unwind_pc_p() = %d\n",
                       gdbarch_unwind_pc_p (gdbarch));
@@ -5100,6 +5106,23 @@ set_gdbarch_valid_disassembler_options (struct gdbarch *gdbarch,
   gdbarch->valid_disassembler_options = valid_disassembler_options;
 }
 
+ULONGEST
+gdbarch_type_align (struct gdbarch *gdbarch, struct type *type)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->type_align != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_type_align called\n");
+  return gdbarch->type_align (gdbarch, type);
+}
+
+void
+set_gdbarch_type_align (struct gdbarch *gdbarch,
+                        gdbarch_type_align_ftype type_align)
+{
+  gdbarch->type_align = type_align;
+}
+
 
 /* Keep a registry of per-architecture data-pointers required by GDB
    modules.  */
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 0084f199d7..3848ec50c7 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -1560,6 +1560,12 @@ extern void set_gdbarch_disassembler_options (struct gdbarch *gdbarch, char ** d
 extern const disasm_options_t * gdbarch_valid_disassembler_options (struct gdbarch *gdbarch);
 extern void set_gdbarch_valid_disassembler_options (struct gdbarch *gdbarch, const disasm_options_t * valid_disassembler_options);
 
+/* Type alignment. */
+
+typedef ULONGEST (gdbarch_type_align_ftype) (struct gdbarch *gdbarch, struct type *type);
+extern ULONGEST gdbarch_type_align (struct gdbarch *gdbarch, struct type *type);
+extern void set_gdbarch_type_align (struct gdbarch *gdbarch, gdbarch_type_align_ftype *type_align);
+
 /* Definition for an unknown syscall, used basically in error-cases.  */
 #define UNKNOWN_SYSCALL (-1)
 
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 4fc54cba9c..bb62e6d620 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -1163,6 +1163,9 @@ m;int;addressable_memory_unit_size;void;;;default_addressable_memory_unit_size;;
 v;char **;disassembler_options;;;0;0;;0;pstring_ptr (gdbarch->disassembler_options)
 v;const disasm_options_t *;valid_disassembler_options;;;0;0;;0;host_address_to_string (gdbarch->valid_disassembler_options)
 
+# Type alignment.
+m;ULONGEST;type_align;struct type *type;type;;default_type_align;;0
+
 EOF
 }
 
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 2efd1264ff..9ecc80f26f 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -3013,6 +3013,128 @@ init_pointer_type (struct objfile *objfile,
   return t;
 }
 
+/* See gdbtypes.h.  */
+
+unsigned
+type_raw_align (struct type *type)
+{
+  if (type->align_log2 != 0)
+    return 1 << (type->align_log2 - 1);
+  return 0;
+}
+
+/* See gdbtypes.h.  */
+
+unsigned
+type_align (struct type *type)
+{
+  unsigned raw_align = type_raw_align (type);
+  if (raw_align != 0)
+    return raw_align;
+
+  ULONGEST align = 0;
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_PTR:
+    case TYPE_CODE_FUNC:
+    case TYPE_CODE_FLAGS:
+    case TYPE_CODE_INT:
+    case TYPE_CODE_FLT:
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_DECFLOAT:
+      {
+	struct gdbarch *arch = get_type_arch (type);
+	align = gdbarch_type_align (arch, type);
+      }
+      break;
+
+    case TYPE_CODE_ARRAY:
+    case TYPE_CODE_COMPLEX:
+    case TYPE_CODE_TYPEDEF:
+      align = type_align (TYPE_TARGET_TYPE (type));
+      break;
+
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+      {
+	if (TYPE_NFIELDS (type) == 0)
+	  {
+	    /* An empty struct has alignment 1.  */
+	    align = 1;
+	    break;
+	  }
+	for (unsigned i = 0; i < TYPE_NFIELDS (type); ++i)
+	  {
+	    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;
+	  }
+      }
+      break;
+
+    case TYPE_CODE_SET:
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_STRING:
+      /* Not sure what to do here, and these can't appear in C or C++
+	 anyway.  */
+      break;
+
+    case TYPE_CODE_METHODPTR:
+    case TYPE_CODE_MEMBERPTR:
+      align = TYPE_LENGTH (type);
+      break;
+
+    case TYPE_CODE_VOID:
+      align = 1;
+      break;
+
+    case TYPE_CODE_ERROR:
+    case TYPE_CODE_METHOD:
+    default:
+      break;
+    }
+
+  if ((align & (align - 1)) != 0)
+    {
+      /* Not a power of 2, so pass.  */
+      align = 0;
+    }
+
+  return align;
+}
+
+/* See gdbtypes.h.  */
+
+bool
+set_type_align (struct type *type, ULONGEST align)
+{
+  /* Must be a power of 2.  Zero is ok.  */
+  gdb_assert ((align & (align - 1)) == 0);
+
+  unsigned result = 0;
+  while (align != 0)
+    {
+      ++result;
+      align >>= 1;
+    }
+
+  if (result >= (1 << TYPE_ALIGN_BITS))
+    return false;
+
+  type->align_log2 = result;
+  return true;
+}
+
 \f
 /* Queries on types.  */
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 552a2a2a16..5f614e573a 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -802,6 +802,10 @@ struct main_type
   struct dynamic_prop_list *dyn_prop_list;
 };
 
+/* * Number of bits allocated for alignment.  */
+
+#define TYPE_ALIGN_BITS 8
+
 /* * A ``struct type'' describes a particular instance of a type, with
    some particular qualification.  */
 
@@ -831,6 +835,14 @@ struct type
 
   struct type *chain;
 
+  /* * The alignment for this type.  Zero means that the alignment was
+     not specified in the debug info.  Note that this is stored in a
+     funny way: as the log base 2 (plus 1) of the alignment; so a
+     value of 1 means the alignment is 1, and a value of 9 means the
+     alignment is 256.  */
+
+  unsigned align_log2 : TYPE_ALIGN_BITS;
+
   /* * Flags specific to this instance of the type, indicating where
      on the ring we are.
 
@@ -841,7 +853,7 @@ struct type
      instance flags are completely inherited from the target type.  No
      qualifiers can be cleared by the typedef.  See also
      check_typedef.  */
-  int instance_flags;
+  unsigned instance_flags : 9;
 
   /* * Length of storage for a value of this type.  The value is the
      expression in host bytes of what sizeof(type) would return.  This
@@ -1292,6 +1304,26 @@ extern void allocate_gnat_aux_type (struct type *);
    so you only have to call check_typedef once.  Since allocate_value
    calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe.  */
 #define TYPE_LENGTH(thistype) (thistype)->length
+
+/* * Return the alignment of the type in target addressable memory
+   units, or 0 if no alignment was specified.  */
+#define TYPE_RAW_ALIGN(thistype) type_raw_align (thistype)
+
+/* * Return the alignment of the type in target addressable memory
+   units, or 0 if no alignment was specified.  */
+extern unsigned type_raw_align (struct type *);
+
+/* * Return the alignment of the type in target addressable memory
+   units.  Return 0 if the alignment cannot be determined; but note
+   that this makes an effort to compute the alignment even it it was
+   not specified in the debug info.  */
+extern unsigned type_align (struct type *);
+
+/* * Set the alignment of the type.  The alignment must be a power of
+   2.  Returns false if the given value does not fit in the available
+   space in struct type.  */
+extern bool set_type_align (struct type *, ULONGEST);
+
 /* * Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real
    type, you need to do TYPE_CODE (check_type (this_type)).  */
 #define TYPE_CODE(thistype) TYPE_MAIN_TYPE(thistype)->code
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index bf4ca54303..fec74ee6c8 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8347,6 +8347,31 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
 }
 
 \f
+
+/* Implement the type_align gdbarch function.  */
+
+static ULONGEST
+i386_type_align (struct gdbarch *gdbarch, struct type *type)
+{
+  type = check_typedef (type);
+
+  if (gdbarch_ptr_bit (gdbarch) == 32)
+    {
+      if ((TYPE_CODE (type) == TYPE_CODE_INT
+	   || TYPE_CODE (type) == TYPE_CODE_FLT)
+	  && TYPE_LENGTH (type) > 4)
+	return 4;
+
+      /* Handle x86's funny long double.  */
+      if (TYPE_CODE (type) == TYPE_CODE_FLT
+	  && gdbarch_long_double_bit (gdbarch) == TYPE_LENGTH (type) * 8)
+	return 4;
+    }
+
+  return TYPE_LENGTH (type);
+}
+
+\f
 /* Note: This is called for both i386 and amd64.  */
 
 static struct gdbarch *
@@ -8405,6 +8430,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->record_regmap = i386_record_regmap;
 
   set_gdbarch_long_long_align_bit (gdbarch, 32);
+  set_gdbarch_type_align (gdbarch, i386_type_align);
 
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
-- 
2.14.3

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFA v2 6/6] Remove long_long_align_bit gdbarch attribute
  2018-04-27 14:01 [RFA v2 0/6] Type alignment Tom Tromey
                   ` (4 preceding siblings ...)
  2018-04-27 14:01 ` [RFA v2 3/6] Reindent type_object_getset in py-type.c Tom Tromey
@ 2018-04-27 14:01 ` Tom Tromey
  2018-04-27 18:47   ` Pedro Alves
  5 siblings, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 14:01 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This removes the long_long_align_bit gdbarch attribute in favor of
type_align.  This uncovered two possible issues.

First, arc-tdep.c claimed that long long alignment was 32 bits, but as
discussed on the list, ARC has a maximum alignment of 32 bits, so I've
added an arc_type_align function to account for this.

Second, jit.c, the sole user of long_long_align_bit, was confusing
"long long" with uint64_t.  The relevant structure is defined in the
JIT API part of the manual as:

     struct jit_code_entry
     {
       struct jit_code_entry *next_entry;
       struct jit_code_entry *prev_entry;
       const char *symfile_addr;
       uint64_t symfile_size;
     };

I've changed this code to use uint64_t.

2018-04-27  Tom Tromey  <tom@tromey.com>

	* jit.c (jit_read_code_entry): Use type_align.
	* i386-tdep.c (i386_gdbarch_init): Don't call
	set_gdbarch_long_long_align_bit.
	* gdbarch.sh: Remove long_long_align_bit.
	* gdbarch.c, gdbarch.h: Rebuild.
	* arc-tdep.c (arc_type_align): New function.
	(arc_gdbarch_init): Use arc_type_align.  Don't call
	set_gdbarch_long_long_align_bit.
---
 gdb/ChangeLog   | 11 +++++++++++
 gdb/arc-tdep.c  | 11 ++++++++++-
 gdb/gdbarch.c   | 23 -----------------------
 gdb/gdbarch.h   |  6 ------
 gdb/gdbarch.sh  |  3 ---
 gdb/i386-tdep.c |  1 -
 gdb/jit.c       |  4 ++--
 7 files changed, 23 insertions(+), 36 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8aa0fc655e..bfe89e18df 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2018-04-27  Tom Tromey  <tom@tromey.com>
+
+	* jit.c (jit_read_code_entry): Use type_align.
+	* i386-tdep.c (i386_gdbarch_init): Don't call
+	set_gdbarch_long_long_align_bit.
+	* gdbarch.sh: Remove long_long_align_bit.
+	* gdbarch.c, gdbarch.h: Rebuild.
+	* arc-tdep.c (arc_type_align): New function.
+	(arc_gdbarch_init): Use arc_type_align.  Don't call
+	set_gdbarch_long_long_align_bit.
+
 2018-04-27  Tom Tromey  <tom@tromey.com>
 
 	* rust-lang.c (rust_type_alignment): Remove.
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index b0d51addd3..286a289a06 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -1957,6 +1957,15 @@ arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
   return TRUE;
 }
 
+/* Implement the type_align gdbarch function.  */
+
+static ULONGEST
+arc_type_align (struct gdbarch *gdbarch, struct type *type)
+{
+  type = check_typedef (type);
+  return std::min<ULONGEST> (4, TYPE_LENGTH (type));
+}
+
 /* Implement the "init" gdbarch method.  */
 
 static struct gdbarch *
@@ -1982,7 +1991,7 @@ arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_int_bit (gdbarch, 32);
   set_gdbarch_long_bit (gdbarch, 32);
   set_gdbarch_long_long_bit (gdbarch, 64);
-  set_gdbarch_long_long_align_bit (gdbarch, 32);
+  set_gdbarch_type_align (gdbarch, arc_type_align);
   set_gdbarch_float_bit (gdbarch, 32);
   set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
   set_gdbarch_double_bit (gdbarch, 64);
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index dd7c89d948..82ac751913 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -175,7 +175,6 @@ struct gdbarch
   int int_bit;
   int long_bit;
   int long_long_bit;
-  int long_long_align_bit;
   int half_bit;
   const struct floatformat ** half_format;
   int float_bit;
@@ -389,7 +388,6 @@ gdbarch_alloc (const struct gdbarch_info *info,
   gdbarch->int_bit = 4*TARGET_CHAR_BIT;
   gdbarch->long_bit = 4*TARGET_CHAR_BIT;
   gdbarch->long_long_bit = 2*gdbarch->long_bit;
-  gdbarch->long_long_align_bit = 2*gdbarch->long_bit;
   gdbarch->half_bit = 2*TARGET_CHAR_BIT;
   gdbarch->float_bit = 4*TARGET_CHAR_BIT;
   gdbarch->double_bit = 8*TARGET_CHAR_BIT;
@@ -530,7 +528,6 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of int_bit, invalid_p == 0 */
   /* Skip verify of long_bit, invalid_p == 0 */
   /* Skip verify of long_long_bit, invalid_p == 0 */
-  /* Skip verify of long_long_align_bit, invalid_p == 0 */
   /* Skip verify of half_bit, invalid_p == 0 */
   if (gdbarch->half_format == 0)
     gdbarch->half_format = floatformats_ieee_half;
@@ -1165,9 +1162,6 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                       "gdbarch_dump: long_double_format = %s\n",
                       pformat (gdbarch->long_double_format));
-  fprintf_unfiltered (file,
-                      "gdbarch_dump: long_long_align_bit = %s\n",
-                      plongest (gdbarch->long_long_align_bit));
   fprintf_unfiltered (file,
                       "gdbarch_dump: long_long_bit = %s\n",
                       plongest (gdbarch->long_long_bit));
@@ -1638,23 +1632,6 @@ set_gdbarch_long_long_bit (struct gdbarch *gdbarch,
   gdbarch->long_long_bit = long_long_bit;
 }
 
-int
-gdbarch_long_long_align_bit (struct gdbarch *gdbarch)
-{
-  gdb_assert (gdbarch != NULL);
-  /* Skip verify of long_long_align_bit, invalid_p == 0 */
-  if (gdbarch_debug >= 2)
-    fprintf_unfiltered (gdb_stdlog, "gdbarch_long_long_align_bit called\n");
-  return gdbarch->long_long_align_bit;
-}
-
-void
-set_gdbarch_long_long_align_bit (struct gdbarch *gdbarch,
-                                 int long_long_align_bit)
-{
-  gdbarch->long_long_align_bit = long_long_align_bit;
-}
-
 int
 gdbarch_half_bit (struct gdbarch *gdbarch)
 {
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 3848ec50c7..b3a15c9898 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -147,12 +147,6 @@ extern void set_gdbarch_long_bit (struct gdbarch *gdbarch, int long_bit);
 extern int gdbarch_long_long_bit (struct gdbarch *gdbarch);
 extern void set_gdbarch_long_long_bit (struct gdbarch *gdbarch, int long_long_bit);
 
-/* Alignment of a long long or unsigned long long for the target
-   machine. */
-
-extern int gdbarch_long_long_align_bit (struct gdbarch *gdbarch);
-extern void set_gdbarch_long_long_align_bit (struct gdbarch *gdbarch, int long_long_align_bit);
-
 /* The ABI default bit-size and format for "half", "float", "double", and
    "long double".  These bit/format pairs should eventually be combined
    into a single object.  For the moment, just initialize them as a pair.
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index bb62e6d620..bf12c68487 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -360,9 +360,6 @@ v;int;long_bit;;;8 * sizeof (long);4*TARGET_CHAR_BIT;;0
 # Number of bits in a long long or unsigned long long for the target
 # machine.
 v;int;long_long_bit;;;8 * sizeof (LONGEST);2*gdbarch->long_bit;;0
-# Alignment of a long long or unsigned long long for the target
-# machine.
-v;int;long_long_align_bit;;;8 * sizeof (LONGEST);2*gdbarch->long_bit;;0
 
 # The ABI default bit-size and format for "half", "float", "double", and
 # "long double".  These bit/format pairs should eventually be combined
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index fec74ee6c8..b359254c75 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8429,7 +8429,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   tdep->record_regmap = i386_record_regmap;
 
-  set_gdbarch_long_long_align_bit (gdbarch, 32);
   set_gdbarch_type_align (gdbarch, i386_type_align);
 
   /* The format used for `long double' on almost all i386 targets is
diff --git a/gdb/jit.c b/gdb/jit.c
index 2f23c058a0..8cd645cb66 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -413,8 +413,8 @@ jit_read_code_entry (struct gdbarch *gdbarch,
   ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
   ptr_size = TYPE_LENGTH (ptr_type);
 
-  /* Figure out where the longlong value will be.  */
-  align_bytes = gdbarch_long_long_align_bit (gdbarch) / 8;
+  /* Figure out where the uint64_t value will be.  */
+  align_bytes = type_align (builtin_type (gdbarch)->builtin_uint64);
   off = 3 * ptr_size;
   off = (off + (align_bytes - 1)) & ~(align_bytes - 1);
 
-- 
2.14.3

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFA v2 2/6] Handle alignof and _Alignof
  2018-04-27 14:01 [RFA v2 0/6] Type alignment Tom Tromey
                   ` (2 preceding siblings ...)
  2018-04-27 14:01 ` [RFA v2 1/6] Add initial type alignment support Tom Tromey
@ 2018-04-27 14:01 ` Tom Tromey
  2018-04-27 14:19   ` Eli Zaretskii
  2018-04-27 18:47   ` Pedro Alves
  2018-04-27 14:01 ` [RFA v2 3/6] Reindent type_object_getset in py-type.c Tom Tromey
  2018-04-27 14:01 ` [RFA v2 6/6] Remove long_long_align_bit gdbarch attribute Tom Tromey
  5 siblings, 2 replies; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 14:01 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This adds alignof and _Alignof to the C/C++ expression parser, and
adds new tests to test the features.  The tests are written to try to
ensure that gdb's knowledge of alignment rules stays in sync with the
compiler's.

2018-04-27  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-27  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.
---
 gdb/ChangeLog                          |  13 +++
 gdb/NEWS                               |   3 +
 gdb/c-exp.y                            |   8 +-
 gdb/c-lang.c                           |   1 +
 gdb/eval.c                             |  13 +++
 gdb/expprint.c                         |   1 +
 gdb/std-operator.def                   |   1 +
 gdb/testsuite/ChangeLog                |   7 ++
 gdb/testsuite/gdb.base/align.exp       | 101 +++++++++++++++++++++++
 gdb/testsuite/gdb.cp/align.exp         | 145 +++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.dwarf2/dw2-align.exp |  83 +++++++++++++++++++
 11 files changed, 375 insertions(+), 1 deletion(-)
 create mode 100644 gdb/testsuite/gdb.base/align.exp
 create mode 100644 gdb/testsuite/gdb.cp/align.exp
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-align.exp

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1b5abb2f0d..73eba465a1 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,16 @@
+2018-04-27  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-27  Tom Tromey  <tom@tromey.com>
 
 	* i386-tdep.c (i386_type_align): New function.
diff --git a/gdb/NEWS b/gdb/NEWS
index 63fe30d175..6631b53475 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 9e2f80889f..3cee544106 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 658c7f7826..15e633f8c8 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 ad66f7c32c..2fdfdf9353 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 c906904599..5985f70a8f 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -846,6 +846,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 87bb518877..1297c1edeb 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 34da102c62..6909e8e0b1 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2018-04-27  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.
+
 2018-04-26  Pedro Alves  <palves@redhat.com>
 
 	* gdb.base/gnu-ifunc.exp (set-break): Test that GDB resolves
diff --git a/gdb/testsuite/gdb.base/align.exp b/gdb/testsuite/gdb.base/align.exp
new file mode 100644
index 0000000000..6c13e24106
--- /dev/null
+++ b/gdb/testsuite/gdb.base/align.exp
@@ -0,0 +1,101 @@
+# 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}
+}
+
+# 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 0000000000..fb5fb46a07
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/align.exp
@@ -0,0 +1,145 @@
+# 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
+}
+
+# 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]; };
+}
+
+# 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 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]
+	&& ($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"
+
+    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"
+    }
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-align.exp b/gdb/testsuite/gdb.dwarf2/dw2-align.exp
new file mode 100644
index 0000000000..2c2faf7591
--- /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"
-- 
2.14.3

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFA v2 0/6] Type alignment
@ 2018-04-27 14:01 Tom Tromey
  2018-04-27 14:01 ` [RFA v2 5/6] Remove rust_type_alignment Tom Tromey
                   ` (5 more replies)
  0 siblings, 6 replies; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 14:01 UTC (permalink / raw)
  To: gdb-patches

This is the second version of the series to add type alignment support
to gdb.  I believe it addresses all review comments.

Regression tested by the buildbot.

Tom

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFA v2 4/6] Expose type alignment on gdb.Type
  2018-04-27 14:01 [RFA v2 0/6] Type alignment Tom Tromey
  2018-04-27 14:01 ` [RFA v2 5/6] Remove rust_type_alignment Tom Tromey
@ 2018-04-27 14:01 ` Tom Tromey
  2018-04-27 14:18   ` Eli Zaretskii
  2018-04-27 18:47   ` Pedro Alves
  2018-04-27 14:01 ` [RFA v2 1/6] Add initial type alignment support Tom Tromey
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 14:01 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This adds an "align" attribute to gdb.Type in the Python API.

2018-04-27  Tom Tromey  <tom@tromey.com>

	* NEWS: Mention Type.align.
	* python/py-type.c (typy_get_align): New function.
	(type_object_getset): Add "align".

2018-04-27  Tom Tromey  <tom@tromey.com>

	* python.texi (Types In Python): Document Type.align.

2018-04-27  Tom Tromey  <tom@tromey.com>

	* gdb.python/py-type.exp: Check align attribute.
	* gdb.python/py-type.c: New "aligncheck" global.
---
 gdb/ChangeLog                        |  6 ++++++
 gdb/NEWS                             |  4 ++++
 gdb/doc/ChangeLog                    |  4 ++++
 gdb/doc/python.texi                  |  7 +++++++
 gdb/python/py-type.c                 | 24 ++++++++++++++++++++++++
 gdb/testsuite/ChangeLog              |  5 +++++
 gdb/testsuite/gdb.python/py-type.c   |  2 ++
 gdb/testsuite/gdb.python/py-type.exp |  4 ++++
 8 files changed, 56 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index caab3a7284..4e1f52dbdf 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2018-04-27  Tom Tromey  <tom@tromey.com>
+
+	* NEWS: Mention Type.align.
+	* python/py-type.c (typy_get_align): New function.
+	(type_object_getset): Add "align".
+
 2018-04-27  Tom Tromey  <tom@tromey.com>
 
 	* python/py-type.c (type_object_getset): Reindent.
diff --git a/gdb/NEWS b/gdb/NEWS
index 6631b53475..6193070023 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -27,6 +27,10 @@ set|show record btrace cpu
   Controls the processor to be used for enabling errata workarounds for
   branch trace decode.
 
+* Python API
+
+  ** Type alignment is now exposed via the "align" attribute of a gdb.Type.
+
 * New targets
 
 RiscV ELF			riscv*-*-elf
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 83d48781f9..4e7c96bfd4 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,7 @@
+2018-04-27  Tom Tromey  <tom@tromey.com>
+
+	* python.texi (Types In Python): Document Type.align.
+
 2018-04-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
 	* gdb.texinfo (Symbols): Mention the fact that "info
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index ebd48fffe7..e5fd713e0a 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -930,6 +930,13 @@ description of the @code{Type.fields} method for a description of the
 
 An instance of @code{Type} has the following attributes:
 
+@defvar Type.align
+The alignment of this type, in bytes.  Type alignment comes from the
+debugging information; if it was not specified, then @value{GDBN} will
+use the relevant ABI to try to determine the alignment.  In some
+cases, even this is not possible, and zero will be returned.
+@end defvar
+
 @defvar Type.code
 The type code for this type.  The type code will be one of the
 @code{TYPE_CODE_} constants defined below.
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index fcd6ed5621..bc49ec66ac 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -730,6 +730,28 @@ typy_get_sizeof (PyObject *self, void *closure)
   return gdb_py_long_from_longest (TYPE_LENGTH (type));
 }
 
+/* Return the alignment of the type represented by SELF, in bytes.  */
+static PyObject *
+typy_get_align (PyObject *self, void *closure)
+{
+  struct type *type = ((type_object *) self)->type;
+
+  ULONGEST align = 0;
+  TRY
+    {
+      align = type_align (type);
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      align = 0;
+    }
+  END_CATCH
+
+  /* Ignore exceptions.  */
+
+  return gdb_py_object_from_ulongest (align);
+}
+
 static struct type *
 typy_lookup_typename (const char *type_name, const struct block *block)
 {
@@ -1410,6 +1432,8 @@ gdbpy_initialize_types (void)
 
 static gdb_PyGetSetDef type_object_getset[] =
 {
+ { "align", typy_get_align, NULL,
+   "The alignment of this type, in bytes.", NULL },
  { "code", typy_get_code, NULL,
    "The code for this type.", NULL },
  { "name", typy_get_name, NULL,
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 6909e8e0b1..40e5bff571 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-04-27  Tom Tromey  <tom@tromey.com>
+
+	* gdb.python/py-type.exp: Check align attribute.
+	* gdb.python/py-type.c: New "aligncheck" global.
+
 2018-04-27  Tom Tromey  <tom@tromey.com>
 
 	PR exp/17095:
diff --git a/gdb/testsuite/gdb.python/py-type.c b/gdb/testsuite/gdb.python/py-type.c
index 2626d4e418..9531c9e6cb 100644
--- a/gdb/testsuite/gdb.python/py-type.c
+++ b/gdb/testsuite/gdb.python/py-type.c
@@ -30,6 +30,8 @@ struct SS
 typedef struct s TS;
 TS ts;
 
+int aligncheck;
+
 #ifdef __cplusplus
 struct C
 {
diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp
index b87e86cdf6..382bdff118 100644
--- a/gdb/testsuite/gdb.python/py-type.exp
+++ b/gdb/testsuite/gdb.python/py-type.exp
@@ -278,6 +278,10 @@ if { [build_inferior "${binfile}" "c"] == 0 } {
   gdb_test "python print(gdb.lookup_type('int').optimized_out())" \
       "<optimized out>"
 
+  set sint [get_sizeof int 0]
+  gdb_test "python print(gdb.parse_and_eval('aligncheck').type.align)" \
+      $sint
+
   with_test_prefix "lang_c" {
       runto_bp "break to inspect struct and array."
       test_fields "c"
-- 
2.14.3

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 4/6] Expose type alignment on gdb.Type
  2018-04-27 14:01 ` [RFA v2 4/6] Expose type alignment on gdb.Type Tom Tromey
@ 2018-04-27 14:18   ` Eli Zaretskii
  2018-04-27 18:47   ` Pedro Alves
  1 sibling, 0 replies; 20+ messages in thread
From: Eli Zaretskii @ 2018-04-27 14:18 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

> From: Tom Tromey <tom@tromey.com>
> Cc: Tom Tromey <tom@tromey.com>
> Date: Fri, 27 Apr 2018 08:01:37 -0600
> 
> This adds an "align" attribute to gdb.Type in the Python API.
> 
> 2018-04-27  Tom Tromey  <tom@tromey.com>
> 
> 	* NEWS: Mention Type.align.
> 	* python/py-type.c (typy_get_align): New function.
> 	(type_object_getset): Add "align".
> 
> 2018-04-27  Tom Tromey  <tom@tromey.com>
> 
> 	* python.texi (Types In Python): Document Type.align.
> 
> 2018-04-27  Tom Tromey  <tom@tromey.com>
> 
> 	* gdb.python/py-type.exp: Check align attribute.
> 	* gdb.python/py-type.c: New "aligncheck" global.

OK for the documentation parts.

Thanks.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 2/6] Handle alignof and _Alignof
  2018-04-27 14:01 ` [RFA v2 2/6] Handle alignof and _Alignof Tom Tromey
@ 2018-04-27 14:19   ` Eli Zaretskii
  2018-04-27 18:47   ` Pedro Alves
  1 sibling, 0 replies; 20+ messages in thread
From: Eli Zaretskii @ 2018-04-27 14:19 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

> From: Tom Tromey <tom@tromey.com>
> Cc: Tom Tromey <tom@tromey.com>
> Date: Fri, 27 Apr 2018 08:01:35 -0600
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 63fe30d175..6631b53475 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

This part is OK, thanks.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 1/6] Add initial type alignment support
  2018-04-27 14:01 ` [RFA v2 1/6] Add initial type alignment support Tom Tromey
@ 2018-04-27 18:46   ` Pedro Alves
  0 siblings, 0 replies; 20+ messages in thread
From: Pedro Alves @ 2018-04-27 18:46 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 04/27/2018 03:01 PM, Tom Tromey wrote:
> This adds some basic type alignment support to gdb.  It changes struct
> type to store the alignment, and updates dwarf2read.c to handle
> DW_AT_alignment.  It also adds a new gdbarch method and updates
> i386-tdep.c.
> 
> None of this new functionality is used anywhere yet, so tests will
> wait until the next patch.

Looks good to me.

TBC, I'm fine with addressing any comments I have made to v1,
if any need to be addressed even, after the initial merge.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 4/6] Expose type alignment on gdb.Type
  2018-04-27 14:01 ` [RFA v2 4/6] Expose type alignment on gdb.Type Tom Tromey
  2018-04-27 14:18   ` Eli Zaretskii
@ 2018-04-27 18:47   ` Pedro Alves
  2018-04-27 20:41     ` Tom Tromey
  1 sibling, 1 reply; 20+ messages in thread
From: Pedro Alves @ 2018-04-27 18:47 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 04/27/2018 03:01 PM, Tom Tromey wrote:

>  static struct type *
>  typy_lookup_typename (const char *type_name, const struct block *block)
>  {
> @@ -1410,6 +1432,8 @@ gdbpy_initialize_types (void)
>  
>  static gdb_PyGetSetDef type_object_getset[] =
>  {
> + { "align", typy_get_align, NULL,
> +   "The alignment of this type, in bytes.", NULL },
>   { "code", typy_get_code, NULL,
>     "The code for this type.", NULL },
>   { "name", typy_get_name, NULL,

I thought it a bit odd to call the field "align" (a verb), so
I went to look what we call the "size" field, thinking that
if it were called literally "size", then "align" would be somewhat
consistent (I would then read "align" as shorthand for "alignment").
But, what I found was that we call the size field "sizeof".
So I think it would be more consistent to call the
alignment field "alignof" instead.  Agree?

Otherwise looks fine to me.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 6/6] Remove long_long_align_bit gdbarch attribute
  2018-04-27 14:01 ` [RFA v2 6/6] Remove long_long_align_bit gdbarch attribute Tom Tromey
@ 2018-04-27 18:47   ` Pedro Alves
  0 siblings, 0 replies; 20+ messages in thread
From: Pedro Alves @ 2018-04-27 18:47 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 04/27/2018 03:01 PM, Tom Tromey wrote:

> 2018-04-27  Tom Tromey  <tom@tromey.com>
> 
> 	* jit.c (jit_read_code_entry): Use type_align.
> 	* i386-tdep.c (i386_gdbarch_init): Don't call
> 	set_gdbarch_long_long_align_bit.
> 	* gdbarch.sh: Remove long_long_align_bit.
> 	* gdbarch.c, gdbarch.h: Rebuild.
> 	* arc-tdep.c (arc_type_align): New function.
> 	(arc_gdbarch_init): Use arc_type_align.  Don't call
> 	set_gdbarch_long_long_align_bit.
OK.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 2/6] Handle alignof and _Alignof
  2018-04-27 14:01 ` [RFA v2 2/6] Handle alignof and _Alignof Tom Tromey
  2018-04-27 14:19   ` Eli Zaretskii
@ 2018-04-27 18:47   ` Pedro Alves
  2018-04-27 20:55     ` Tom Tromey
  2018-04-30 16:50     ` Tom Tromey
  1 sibling, 2 replies; 20+ messages in thread
From: Pedro Alves @ 2018-04-27 18:47 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 04/27/2018 03:01 PM, Tom Tromey wrote:
> This adds alignof and _Alignof to the C/C++ expression parser, and
> adds new tests to test the features.  The tests are written to try to
> ensure that gdb's knowledge of alignment rules stays in sync with the
> compiler's.

This looks good to me.  A few comments on additional tests below,
but there's no need for another round of review for those.

> +++ b/gdb/testsuite/gdb.cp/align.exp
> @@ -0,0 +1,145 @@

...

> +
> +# 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]; };

Sorry to be a drag, but I think it'd be good to add a few
more tests here:

 - alignof(typedef)

   (to make sure we're not missing a check_typedef
   call somewhere.  e.g., add "typedef arrstruct arrstruct_t",
   then add arrstruct_t to the list of tested types.

 - alignof(a class with a base class).

   E.g.,:

    struct A { int i;};
    struct B : A { char c; };

   and then check alignof(B).

   multiple and virtual inheritance might be worth
   testing too, not sure whether the code paths are
   (and will always be) the same.

 - alignof(array-type)

   This is what I actually meant by arrays in v1.  E.g.:

     alignof (int[3])

   It might be we don't parse that.  Not sure.  If it's hard,
   it's ok to punt, but then it'd be good to still add the test
   and kfail it.

> +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]
> +	&& ($type == "double" || $type == "long long"
> +	    || $type == "unsigned long long")} {
> +	setup_xfail *-*-*

It seems like we can check for gcc version with test_compiler_info.
Maybe go ahead and limit the xfail to:

  [test_compiler_info {gcc-[0-8]-*}]

?

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 3/6] Reindent type_object_getset in py-type.c
  2018-04-27 14:01 ` [RFA v2 3/6] Reindent type_object_getset in py-type.c Tom Tromey
@ 2018-04-27 18:47   ` Pedro Alves
  2018-04-27 20:39     ` Tom Tromey
  0 siblings, 1 reply; 20+ messages in thread
From: Pedro Alves @ 2018-04-27 18:47 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 04/27/2018 03:01 PM, Tom Tromey wrote:
> I noticed that type_object_getset was indented incorrectly.  This
> fixes it.
> 

...

>  static gdb_PyGetSetDef type_object_getset[] =
>  {
> -  { "code", typy_get_code, NULL,
> -    "The code for this type.", NULL },
> -  { "name", typy_get_name, NULL,
> -    "The name for this type, or None.", NULL },
> -  { "sizeof", typy_get_sizeof, NULL,
> -    "The size of this type, in bytes.", NULL },
> -  { "tag", typy_get_tag, NULL,
> -    "The tag name for this type, or None.", NULL },
> -  { NULL }
> + { "code", typy_get_code, NULL,
> +   "The code for this type.", NULL },
> + { "name", typy_get_name, NULL,
> +   "The name for this type, or None.", NULL },
> + { "sizeof", typy_get_sizeof, NULL,
> +   "The size of this type, in bytes.", NULL },
> + { "tag", typy_get_tag, NULL,
> +   "The tag name for this type, or None.", NULL },
> + { NULL }
>  };

Hmm, AFAICT this is currently indented like other similar
arrays.  My emacs seems to agree with the current alignment
too.  Isn't two spaces the usual?

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 3/6] Reindent type_object_getset in py-type.c
  2018-04-27 18:47   ` Pedro Alves
@ 2018-04-27 20:39     ` Tom Tromey
  0 siblings, 0 replies; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 20:39 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Tom Tromey, gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> Hmm, AFAICT this is currently indented like other similar
Pedro> arrays.  My emacs seems to agree with the current alignment
Pedro> too.  Isn't two spaces the usual?

Yeah.  I think I have a bad version of cc-mode at the moment.
I'll drop this patch.

Tom

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 4/6] Expose type alignment on gdb.Type
  2018-04-27 18:47   ` Pedro Alves
@ 2018-04-27 20:41     ` Tom Tromey
  0 siblings, 0 replies; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 20:41 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Tom Tromey, gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> So I think it would be more consistent to call the
Pedro> alignment field "alignof" instead.  Agree?

I renamed it.

Tom

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 2/6] Handle alignof and _Alignof
  2018-04-27 18:47   ` Pedro Alves
@ 2018-04-27 20:55     ` Tom Tromey
  2018-04-27 20:59       ` Tom Tromey
  2018-04-30 16:50     ` Tom Tromey
  1 sibling, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 20:55 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Tom Tromey, gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro>  - alignof(typedef)

Pedro>    (to make sure we're not missing a check_typedef
Pedro>    call somewhere.  e.g., add "typedef arrstruct arrstruct_t",
Pedro>    then add arrstruct_t to the list of tested types.

This one is in the patch already:

+    puts $outfile "typedef $type t_$utype;"
+    puts $outfile "t_$utype item_t_$utype;"
[...]
+    gdb_test "print alignof(t_$utype)" " = $expected"

I'll add the others though.

Tom

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 2/6] Handle alignof and _Alignof
  2018-04-27 20:55     ` Tom Tromey
@ 2018-04-27 20:59       ` Tom Tromey
  0 siblings, 0 replies; 20+ messages in thread
From: Tom Tromey @ 2018-04-27 20:59 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Pedro Alves, gdb-patches

>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
Pedro> - alignof(typedef)

Pedro> (to make sure we're not missing a check_typedef
Pedro> call somewhere.  e.g., add "typedef arrstruct arrstruct_t",
Pedro> then add arrstruct_t to the list of tested types.

Tom> This one is in the patch already:
[..]


I forgot to mention, but for C++ specifically, there's an issue with
using typedefs as template parameters:

https://sourceware.org/bugzilla/show_bug.cgi?id=23103

... which is why this particular form of the test isn't in there.

Tom

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 2/6] Handle alignof and _Alignof
  2018-04-27 18:47   ` Pedro Alves
  2018-04-27 20:55     ` Tom Tromey
@ 2018-04-30 16:50     ` Tom Tromey
  2018-04-30 17:17       ` Pedro Alves
  1 sibling, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2018-04-30 16:50 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Tom Tromey, gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> This looks good to me.  A few comments on additional tests below,
Pedro> but there's no need for another round of review for those.

This patch will need another review since I added some new stuff.

Pedro> Sorry to be a drag, but I think it'd be good to add a few
Pedro> more tests here:

Pedro>  - alignof(typedef)

This was already in there.

Pedro>  - alignof(a class with a base class).

Done.

Pedro>  - alignof(array-type)

Done.

Pedro> Maybe go ahead and limit the xfail to:

Pedro>   [test_compiler_info {gcc-[0-8]-*}]

Done.


This version includes a couple of new gdb_caching_procs to do the
__int128 check.

Tom


commit 16be2868c298498eb936e57943a781701925bed9
Author: Tom Tromey <tom@tromey.com>
Date:   Fri Apr 20 13:40:29 2018 -0600

    Handle alignof and _Alignof
    
    This adds alignof and _Alignof to the C/C++ expression parser, and
    adds new tests to test the features.  The tests are written to try to
    ensure that gdb's knowledge of alignment rules stays in sync with the
    compiler's.
    
    2018-04-27  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>
    
            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.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9a6952ae62..2a5bf3e603 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,16 @@
+2018-04-27  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-27  Tom Tromey  <tom@tromey.com>
 
 	* i386-tdep.c (i386_type_align): New function.
diff --git a/gdb/NEWS b/gdb/NEWS
index 63fe30d175..6631b53475 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 9e2f80889f..3cee544106 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 658c7f7826..15e633f8c8 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 ad66f7c32c..2fdfdf9353 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 047ec11df1..70d355d369 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 87bb518877..1297c1edeb 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 22cf4ff47a..e8b55aac90 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 0000000000..dfe53728ff
--- /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 0000000000..7d5955e53b
--- /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 0000000000..2c2faf7591
--- /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 4d48f5e3ad..0f05d043f2 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.
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFA v2 2/6] Handle alignof and _Alignof
  2018-04-30 16:50     ` Tom Tromey
@ 2018-04-30 17:17       ` Pedro Alves
  0 siblings, 0 replies; 20+ messages in thread
From: Pedro Alves @ 2018-04-30 17:17 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 04/30/2018 05:49 PM, Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
> 
> Pedro> This looks good to me.  A few comments on additional tests below,
> Pedro> but there's no need for another round of review for those.
> 
> This patch will need another review since I added some new stuff.

Looks good, thanks.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2018-04-30 17:17 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-27 14:01 [RFA v2 0/6] Type alignment Tom Tromey
2018-04-27 14:01 ` [RFA v2 5/6] Remove rust_type_alignment Tom Tromey
2018-04-27 14:01 ` [RFA v2 4/6] Expose type alignment on gdb.Type Tom Tromey
2018-04-27 14:18   ` Eli Zaretskii
2018-04-27 18:47   ` Pedro Alves
2018-04-27 20:41     ` Tom Tromey
2018-04-27 14:01 ` [RFA v2 1/6] Add initial type alignment support Tom Tromey
2018-04-27 18:46   ` Pedro Alves
2018-04-27 14:01 ` [RFA v2 2/6] Handle alignof and _Alignof Tom Tromey
2018-04-27 14:19   ` Eli Zaretskii
2018-04-27 18:47   ` Pedro Alves
2018-04-27 20:55     ` Tom Tromey
2018-04-27 20:59       ` Tom Tromey
2018-04-30 16:50     ` Tom Tromey
2018-04-30 17:17       ` Pedro Alves
2018-04-27 14:01 ` [RFA v2 3/6] Reindent type_object_getset in py-type.c Tom Tromey
2018-04-27 18:47   ` Pedro Alves
2018-04-27 20:39     ` Tom Tromey
2018-04-27 14:01 ` [RFA v2 6/6] Remove long_long_align_bit gdbarch attribute Tom Tromey
2018-04-27 18:47   ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).