Add a fall-through comment to stabsread.c
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index fb109649ffc4e692a9b9ec3fde5358a20410c92d..26ec5efc286609a5275fcec4e959adb170962bf2 100644 (file)
@@ -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)
@@ -10575,7 +10578,8 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       cu->processing_has_namespace_info = 1;
       if (read_namespace_alias (die, cu))
        break;
-      /* The declaration is not a global namespace alias: fall through.  */
+      /* The declaration is not a global namespace alias.  */
+      /* Fall through.  */
     case DW_TAG_imported_module:
       cu->processing_has_namespace_info = 1;
       if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
@@ -15578,6 +15582,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 +15768,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 +16214,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 +16241,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 +16468,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 +16534,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 +16907,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 +16932,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 +16947,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 +17017,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 +17504,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 +17768,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.  */
This page took 0.032415 seconds and 4 git commands to generate.