From: Eric Botcazou Date: Thu, 19 Oct 2017 13:50:10 +0000 (+0000) Subject: re PR debug/82509 (DW_AT_endianity issues with attribute scalar_storage_order) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=426776f1b5866046e06fd373fcc39f568c292878;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 553692dc73a..d8619c106ca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2017-10-19 Eric Botcazou + + 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 * config/arm/arm.c (align_ok_ldrd_strd): New function. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index beab5e4ce8e..ec9b40602b1 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -5364,6 +5364,16 @@ splice_child_die (dw_die_ref parent, dw_die_ref child) 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->die_tag = tag_value; + return die; +} + /* 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 associated tree T must be supplied to determine parenthood @@ -5372,9 +5382,7 @@ splice_child_die (dw_die_ref parent, dw_die_ref child) static inline dw_die_ref new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t) { - dw_die_ref die = ggc_cleared_alloc (); - - die->die_tag = tag_value; + dw_die_ref die = new_die_raw (tag_value); if (parent_die != NULL) add_child_die (parent_die, die); @@ -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 new_die because we don't want to end up in the limbo list. */ - dw_die_ref ref = ggc_cleared_alloc (); - ref->die_tag = die->die_tag; + dw_die_ref ref = new_die_raw (die->die_tag); ref->die_id.die_symbol = IDENTIFIER_POINTER (get_identifier (symbol)); ref->die_offset = offset; ref->with_offset = 1; @@ -7712,13 +7719,10 @@ should_move_die_to_comdat (dw_die_ref die) static dw_die_ref clone_die (dw_die_ref die) { - dw_die_ref clone; + dw_die_ref clone = new_die_raw (die->die_tag); dw_attr_node *a; unsigned ix; - clone = ggc_cleared_alloc (); - clone->die_tag = die->die_tag; - FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a) add_dwarf_attr (clone, a); @@ -7762,8 +7766,7 @@ clone_as_declaration (dw_die_ref die) return clone; } - clone = ggc_cleared_alloc (); - clone->die_tag = die->die_tag; + clone = new_die_raw (die->die_tag); FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a) { @@ -12090,9 +12093,6 @@ base_type_die (tree type, bool reverse) struct fixed_point_type_info fpt_info; 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, use the base type. See subrange_type_for_debug_p. */ if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE) @@ -12185,7 +12185,7 @@ base_type_die (tree type, bool reverse) 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, int_size_in_bytes (type)); @@ -12241,8 +12241,6 @@ base_type_die (tree type, bool reverse) | dw_scalar_form_reference, NULL); - add_pubtype (type, base_type_result); - return base_type_result; } @@ -12270,8 +12268,6 @@ is_base_type (tree type) { switch (TREE_CODE (type)) { - case ERROR_MARK: - case VOID_TYPE: case INTEGER_TYPE: case REAL_TYPE: case FIXED_POINT_TYPE: @@ -12280,6 +12276,7 @@ is_base_type (tree type) case POINTER_BOUNDS_TYPE: return 1; + case VOID_TYPE: case ARRAY_TYPE: case RECORD_TYPE: case UNION_TYPE: @@ -12485,6 +12482,8 @@ modified_type_die (tree type, int cv_quals, bool reverse, /* Only these cv-qualifiers are currently handled. */ const int cv_qual_mask = (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC); + const bool reverse_base_type + = need_endianity_attribute_p (reverse) && is_base_type (type); if (code == ERROR_MARK) return NULL; @@ -12535,29 +12534,33 @@ modified_type_die (tree type, int cv_quals, bool reverse, qualified_type = size_type_node; } - /* If we do, then we can just use its DIE, if it exists. */ if (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 - && (!need_endianity_attribute_p (reverse) - || !is_base_type (type) - || get_AT_unsigned (mod_type_die, DW_AT_endianity))) + && (!reverse_base_type + || ((mod_type_die = mod_type_die->die_sib) != NULL + && get_AT_unsigned (mod_type_die, DW_AT_endianity)))) return mod_type_die; } name = qualified_type ? TYPE_NAME (qualified_type) : NULL; /* 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)) { 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); @@ -12670,8 +12673,7 @@ modified_type_die (tree type, int cv_quals, bool reverse, } if (first) { - d = ggc_cleared_alloc (); - d->die_tag = dwarf_qual_info[i].t; + d = new_die_raw (dwarf_qual_info[i].t); add_child_die_after (mod_scope, d, last); last = d; } @@ -12729,7 +12731,21 @@ modified_type_die (tree type, int cv_quals, bool reverse, item_type = TREE_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 { gen_type_die (type, context_die); @@ -12791,7 +12807,7 @@ modified_type_die (tree type, int cv_quals, bool reverse, name ? IDENTIFIER_POINTER (name) : "__unknown__"); } - if (qualified_type) + if (qualified_type && !reverse_base_type) equate_type_number_to_die (qualified_type, mod_type_die); if (item_type) @@ -20500,8 +20516,7 @@ dwarf2out_vms_debug_main_pointer (void) dw_die_ref die; /* Allocate the VMS debug main subprogram die. */ - die = ggc_cleared_alloc (); - die->die_tag = DW_TAG_subprogram; + die = new_die_raw (DW_TAG_subprogram); add_name_attribute (die, VMS_DEBUG_MAIN_POINTER); ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL, current_function_funcdef_no); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8f17115b364..1488f6fc03b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2017-10-19 Eric Botcazou + + * 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 PR target/82445 diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/sso-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/sso-1.c new file mode 100644 index 00000000000..698c636a130 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/sso-1.c @@ -0,0 +1,22 @@ +/* { 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 S0 { int i; }; + +struct S1 { int i; struct S0 s; } REVERSE_SSO; + +struct S2 { int a[4]; struct S0 s; } REVERSE_SSO; + +struct S0 s0; +struct S1 s1; +struct S2 s2; + +/* Verify that we have endianity on the common base type of 'i' in S1 and of + the element of 'a' in S2. */ +/* { dg-final { scan-assembler-times " DW_AT_endianity" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/sso-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/sso-2.c new file mode 100644 index 00000000000..0965084d260 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/sso-2.c @@ -0,0 +1,28 @@ +/* { 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 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/sso-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/sso-3.c new file mode 100644 index 00000000000..004327c78ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/sso-3.c @@ -0,0 +1,31 @@ +/* { 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 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/sso.c b/gcc/testsuite/gcc.dg/debug/dwarf2/sso.c deleted file mode 100644 index 698c636a130..00000000000 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/sso.c +++ /dev/null @@ -1,22 +0,0 @@ -/* { 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 S0 { int i; }; - -struct S1 { int i; struct S0 s; } REVERSE_SSO; - -struct S2 { int a[4]; struct S0 s; } REVERSE_SSO; - -struct S0 s0; -struct S1 s1; -struct S2 s2; - -/* Verify that we have endianity on the common base type of 'i' in S1 and of - the element of 'a' in S2. */ -/* { dg-final { scan-assembler-times " DW_AT_endianity" 1 } } */