Commit 426776f1 by Eric Botcazou Committed by Eric Botcazou

re PR debug/82509 (DW_AT_endianity issues with attribute scalar_storage_order)

	PR debug/82509
	* dwarf2out.c (new_die_raw): New static inline function.
	(new_die): Use it to create the DIE.
	(add_AT_external_die_ref): Likewise.
	(clone_die): Likewise.
	(clone_as_declaration): Likewise.
	(dwarf2out_vms_debug_main_pointer): Likewise.
	(base_type_die): Likewise.  Remove early return for corner cases.
	Do not call add_pubtype on the DIE here.
	(is_base_type): Remove ERROR_MARK and return 0 for VOID_TYPE.
	(modified_type_die): Adjust the lookup for reverse order DIEs.  Skip
	typedefs for base types with DW_AT_endianity.  Make sure a DIE with
	native order exists for base types, attach the DIE manually and call
	add_pubtype on it.  Do not equate a reverse order DIE to the type.

From-SVN: r253893
parent 3bb3d60b
2017-10-19 Eric Botcazou <ebotcazou@adacore.com>
PR debug/82509
* dwarf2out.c (new_die_raw): New static inline function.
(new_die): Use it to create the DIE.
(add_AT_external_die_ref): Likewise.
(clone_die): Likewise.
(clone_as_declaration): Likewise.
(dwarf2out_vms_debug_main_pointer): Likewise.
(base_type_die): Likewise. Remove early return for corner cases.
Do not call add_pubtype on the DIE here.
(is_base_type): Remove ERROR_MARK and return 0 for VOID_TYPE.
(modified_type_die): Adjust the lookup for reverse order DIEs. Skip
typedefs for base types with DW_AT_endianity. Make sure a DIE with
native order exists for base types, attach the DIE manually and call
add_pubtype on it. Do not equate a reverse order DIE to the type.
2017-10-19 Richard Earnshaw <rearnsha@arm.com> 2017-10-19 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm.c (align_ok_ldrd_strd): New function. * config/arm/arm.c (align_ok_ldrd_strd): New function.
...@@ -5364,6 +5364,16 @@ splice_child_die (dw_die_ref parent, dw_die_ref child) ...@@ -5364,6 +5364,16 @@ splice_child_die (dw_die_ref parent, dw_die_ref child)
reparent_child (child, parent); reparent_child (child, parent);
} }
/* Create and return a new die with TAG_VALUE as tag. */
static inline dw_die_ref
new_die_raw (enum dwarf_tag tag_value)
{
dw_die_ref die = ggc_cleared_alloc<die_node> ();
die->die_tag = tag_value;
return die;
}
/* Create and return a new die with a parent of PARENT_DIE. If /* Create and return a new die with a parent of PARENT_DIE. If
PARENT_DIE is NULL, the new DIE is placed in limbo and an PARENT_DIE is NULL, the new DIE is placed in limbo and an
associated tree T must be supplied to determine parenthood associated tree T must be supplied to determine parenthood
...@@ -5372,9 +5382,7 @@ splice_child_die (dw_die_ref parent, dw_die_ref child) ...@@ -5372,9 +5382,7 @@ splice_child_die (dw_die_ref parent, dw_die_ref child)
static inline dw_die_ref static inline dw_die_ref
new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t) new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t)
{ {
dw_die_ref die = ggc_cleared_alloc<die_node> (); dw_die_ref die = new_die_raw (tag_value);
die->die_tag = tag_value;
if (parent_die != NULL) if (parent_die != NULL)
add_child_die (parent_die, die); add_child_die (parent_die, die);
...@@ -5568,8 +5576,7 @@ add_AT_external_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind, ...@@ -5568,8 +5576,7 @@ add_AT_external_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind,
{ {
/* Create a fake DIE that contains the reference. Don't use /* Create a fake DIE that contains the reference. Don't use
new_die because we don't want to end up in the limbo list. */ new_die because we don't want to end up in the limbo list. */
dw_die_ref ref = ggc_cleared_alloc<die_node> (); dw_die_ref ref = new_die_raw (die->die_tag);
ref->die_tag = die->die_tag;
ref->die_id.die_symbol = IDENTIFIER_POINTER (get_identifier (symbol)); ref->die_id.die_symbol = IDENTIFIER_POINTER (get_identifier (symbol));
ref->die_offset = offset; ref->die_offset = offset;
ref->with_offset = 1; ref->with_offset = 1;
...@@ -7712,13 +7719,10 @@ should_move_die_to_comdat (dw_die_ref die) ...@@ -7712,13 +7719,10 @@ should_move_die_to_comdat (dw_die_ref die)
static dw_die_ref static dw_die_ref
clone_die (dw_die_ref die) clone_die (dw_die_ref die)
{ {
dw_die_ref clone; dw_die_ref clone = new_die_raw (die->die_tag);
dw_attr_node *a; dw_attr_node *a;
unsigned ix; unsigned ix;
clone = ggc_cleared_alloc<die_node> ();
clone->die_tag = die->die_tag;
FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a) FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
add_dwarf_attr (clone, a); add_dwarf_attr (clone, a);
...@@ -7762,8 +7766,7 @@ clone_as_declaration (dw_die_ref die) ...@@ -7762,8 +7766,7 @@ clone_as_declaration (dw_die_ref die)
return clone; return clone;
} }
clone = ggc_cleared_alloc<die_node> (); clone = new_die_raw (die->die_tag);
clone->die_tag = die->die_tag;
FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a) FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
{ {
...@@ -12090,9 +12093,6 @@ base_type_die (tree type, bool reverse) ...@@ -12090,9 +12093,6 @@ base_type_die (tree type, bool reverse)
struct fixed_point_type_info fpt_info; struct fixed_point_type_info fpt_info;
tree type_bias = NULL_TREE; tree type_bias = NULL_TREE;
if (TREE_CODE (type) == ERROR_MARK || TREE_CODE (type) == VOID_TYPE)
return 0;
/* If this is a subtype that should not be emitted as a subrange type, /* If this is a subtype that should not be emitted as a subrange type,
use the base type. See subrange_type_for_debug_p. */ use the base type. See subrange_type_for_debug_p. */
if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE) if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE)
...@@ -12185,7 +12185,7 @@ base_type_die (tree type, bool reverse) ...@@ -12185,7 +12185,7 @@ base_type_die (tree type, bool reverse)
gcc_unreachable (); gcc_unreachable ();
} }
base_type_result = new_die (DW_TAG_base_type, comp_unit_die (), type); base_type_result = new_die_raw (DW_TAG_base_type);
add_AT_unsigned (base_type_result, DW_AT_byte_size, add_AT_unsigned (base_type_result, DW_AT_byte_size,
int_size_in_bytes (type)); int_size_in_bytes (type));
...@@ -12241,8 +12241,6 @@ base_type_die (tree type, bool reverse) ...@@ -12241,8 +12241,6 @@ base_type_die (tree type, bool reverse)
| dw_scalar_form_reference, | dw_scalar_form_reference,
NULL); NULL);
add_pubtype (type, base_type_result);
return base_type_result; return base_type_result;
} }
...@@ -12270,8 +12268,6 @@ is_base_type (tree type) ...@@ -12270,8 +12268,6 @@ is_base_type (tree type)
{ {
switch (TREE_CODE (type)) switch (TREE_CODE (type))
{ {
case ERROR_MARK:
case VOID_TYPE:
case INTEGER_TYPE: case INTEGER_TYPE:
case REAL_TYPE: case REAL_TYPE:
case FIXED_POINT_TYPE: case FIXED_POINT_TYPE:
...@@ -12280,6 +12276,7 @@ is_base_type (tree type) ...@@ -12280,6 +12276,7 @@ is_base_type (tree type)
case POINTER_BOUNDS_TYPE: case POINTER_BOUNDS_TYPE:
return 1; return 1;
case VOID_TYPE:
case ARRAY_TYPE: case ARRAY_TYPE:
case RECORD_TYPE: case RECORD_TYPE:
case UNION_TYPE: case UNION_TYPE:
...@@ -12485,6 +12482,8 @@ modified_type_die (tree type, int cv_quals, bool reverse, ...@@ -12485,6 +12482,8 @@ modified_type_die (tree type, int cv_quals, bool reverse,
/* Only these cv-qualifiers are currently handled. */ /* Only these cv-qualifiers are currently handled. */
const int cv_qual_mask = (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE const int cv_qual_mask = (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC); | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC);
const bool reverse_base_type
= need_endianity_attribute_p (reverse) && is_base_type (type);
if (code == ERROR_MARK) if (code == ERROR_MARK)
return NULL; return NULL;
...@@ -12535,29 +12534,33 @@ modified_type_die (tree type, int cv_quals, bool reverse, ...@@ -12535,29 +12534,33 @@ modified_type_die (tree type, int cv_quals, bool reverse,
qualified_type = size_type_node; qualified_type = size_type_node;
} }
/* If we do, then we can just use its DIE, if it exists. */ /* If we do, then we can just use its DIE, if it exists. */
if (qualified_type) if (qualified_type)
{ {
mod_type_die = lookup_type_die (qualified_type); mod_type_die = lookup_type_die (qualified_type);
/* DW_AT_endianity doesn't come from a qualifier on the type. */ /* DW_AT_endianity doesn't come from a qualifier on the type, so it is
dealt with specially: the DIE with the attribute, if it exists, is
placed immediately after the regular DIE for the same base type. */
if (mod_type_die if (mod_type_die
&& (!need_endianity_attribute_p (reverse) && (!reverse_base_type
|| !is_base_type (type) || ((mod_type_die = mod_type_die->die_sib) != NULL
|| get_AT_unsigned (mod_type_die, DW_AT_endianity))) && get_AT_unsigned (mod_type_die, DW_AT_endianity))))
return mod_type_die; return mod_type_die;
} }
name = qualified_type ? TYPE_NAME (qualified_type) : NULL; name = qualified_type ? TYPE_NAME (qualified_type) : NULL;
/* Handle C typedef types. */ /* Handle C typedef types. */
if (name && TREE_CODE (name) == TYPE_DECL && DECL_ORIGINAL_TYPE (name) if (name
&& TREE_CODE (name) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (name)
&& !DECL_ARTIFICIAL (name)) && !DECL_ARTIFICIAL (name))
{ {
tree dtype = TREE_TYPE (name); tree dtype = TREE_TYPE (name);
if (qualified_type == dtype) /* Skip the typedef for base types with DW_AT_endianity, no big deal. */
if (qualified_type == dtype && !reverse_base_type)
{ {
tree origin = decl_ultimate_origin (name); tree origin = decl_ultimate_origin (name);
...@@ -12670,8 +12673,7 @@ modified_type_die (tree type, int cv_quals, bool reverse, ...@@ -12670,8 +12673,7 @@ modified_type_die (tree type, int cv_quals, bool reverse,
} }
if (first) if (first)
{ {
d = ggc_cleared_alloc<die_node> (); d = new_die_raw (dwarf_qual_info[i].t);
d->die_tag = dwarf_qual_info[i].t;
add_child_die_after (mod_scope, d, last); add_child_die_after (mod_scope, d, last);
last = d; last = d;
} }
...@@ -12729,7 +12731,21 @@ modified_type_die (tree type, int cv_quals, bool reverse, ...@@ -12729,7 +12731,21 @@ modified_type_die (tree type, int cv_quals, bool reverse,
item_type = TREE_TYPE (type); item_type = TREE_TYPE (type);
} }
else if (is_base_type (type)) else if (is_base_type (type))
mod_type_die = base_type_die (type, reverse); {
mod_type_die = base_type_die (type, reverse);
/* The DIE with DW_AT_endianity is placed right after the naked DIE. */
if (reverse_base_type)
{
dw_die_ref after_die
= modified_type_die (type, cv_quals, false, context_die);
add_child_die_after (comp_unit_die (), mod_type_die, after_die);
}
else
add_child_die (comp_unit_die (), mod_type_die);
add_pubtype (type, mod_type_die);
}
else else
{ {
gen_type_die (type, context_die); gen_type_die (type, context_die);
...@@ -12791,7 +12807,7 @@ modified_type_die (tree type, int cv_quals, bool reverse, ...@@ -12791,7 +12807,7 @@ modified_type_die (tree type, int cv_quals, bool reverse,
name ? IDENTIFIER_POINTER (name) : "__unknown__"); name ? IDENTIFIER_POINTER (name) : "__unknown__");
} }
if (qualified_type) if (qualified_type && !reverse_base_type)
equate_type_number_to_die (qualified_type, mod_type_die); equate_type_number_to_die (qualified_type, mod_type_die);
if (item_type) if (item_type)
...@@ -20500,8 +20516,7 @@ dwarf2out_vms_debug_main_pointer (void) ...@@ -20500,8 +20516,7 @@ dwarf2out_vms_debug_main_pointer (void)
dw_die_ref die; dw_die_ref die;
/* Allocate the VMS debug main subprogram die. */ /* Allocate the VMS debug main subprogram die. */
die = ggc_cleared_alloc<die_node> (); die = new_die_raw (DW_TAG_subprogram);
die->die_tag = DW_TAG_subprogram;
add_name_attribute (die, VMS_DEBUG_MAIN_POINTER); add_name_attribute (die, VMS_DEBUG_MAIN_POINTER);
ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL, ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL,
current_function_funcdef_no); current_function_funcdef_no);
......
2017-10-19 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/debug/dwarf2/sso.c: Rename into...
* gcc.dg/debug/dwarf2/sso-1.c: ...this.
* gcc.dg/debug/dwarf2/sso-2.c: New test.
* gcc.dg/debug/dwarf2/sso-3.c: Likewise.
2017-10-19 Richard Earnshaw <rearnsha@arm.com> 2017-10-19 Richard Earnshaw <rearnsha@arm.com>
PR target/82445 PR target/82445
......
/* { dg-do compile } */
/* { dg-options "-gdwarf-3 -dA" } */
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define REVERSE_SSO __attribute__((scalar_storage_order("big-endian")));
#else
#define REVERSE_SSO __attribute__((scalar_storage_order("little-endian")));
#endif
struct reverse
{
int i;
short a[4];
} REVERSE_SSO;
struct native
{
int i;
short a[4];
};
struct reverse R;
struct native N;
/* Verify that we have endianity on the common base type of 'i' and the
* element of 'a' in the first 2 structures. */
/* { dg-final { scan-assembler-times " DW_AT_endianity" 2 } } */
/* { dg-final { scan-assembler-times "DIE \\(\[0-9a-z\]*\\) DW_TAG_base_type" 5 } } */
/* { dg-do compile } */
/* { dg-options "-gdwarf-3 -dA" } */
typedef int int_t;
typedef short short_t;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define REVERSE_SSO __attribute__((scalar_storage_order("big-endian")));
#else
#define REVERSE_SSO __attribute__((scalar_storage_order("little-endian")));
#endif
struct reverse
{
int_t i;
short_t a[4];
} REVERSE_SSO;
struct native
{
int_t i;
short_t a[4];
};
struct reverse R;
struct native N;
/* Verify that we have endianity on the common base type of 'i' and the
* element of 'a' in the first 2 structures. */
/* { dg-final { scan-assembler-times " DW_AT_endianity" 2 } } */
/* { dg-final { scan-assembler-times "DIE \\(\[0-9a-z\]*\\) DW_TAG_base_type" 5 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment