The following avoids duplicate DW_AT_const_value attributesin the way
probably intended by the early-debug merge which added the get_AT
check in the first place.

Bootstrapped & tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-09-21  Richard Biener  <rguent...@suse.de>

        PR debug/67664
        * dwarf2out.c (add_location_or_const_value_attribute): Remove
        attribute parameter.  Early exit if either DW_AT_const_value
        or DW_AT_location are present already.
        (gen_variable_die): Adjust caller.
        (dwarf2out_late_global_decl): Likewise.

        * g++.dg/debug/dwarf2/pr67764.C: New testcase.

Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c     (revision 227899)
--- gcc/dwarf2out.c     (working copy)
*************** static void insert_int (HOST_WIDE_INT, u
*** 3254,3261 ****
  static void insert_wide_int (const wide_int &, unsigned char *, int);
  static void insert_float (const_rtx, unsigned char *);
  static rtx rtl_for_decl_location (tree);
! static bool add_location_or_const_value_attribute (dw_die_ref, tree, bool,
!                                                  enum dwarf_attribute);
  static bool tree_add_const_value_attribute (dw_die_ref, tree);
  static bool tree_add_const_value_attribute_for_decl (dw_die_ref, tree);
  static void add_name_attribute (dw_die_ref, const char *);
--- 3254,3260 ----
  static void insert_wide_int (const wide_int &, unsigned char *, int);
  static void insert_float (const_rtx, unsigned char *);
  static rtx rtl_for_decl_location (tree);
! static bool add_location_or_const_value_attribute (dw_die_ref, tree, bool);
  static bool tree_add_const_value_attribute (dw_die_ref, tree);
  static bool tree_add_const_value_attribute_for_decl (dw_die_ref, tree);
  static void add_name_attribute (dw_die_ref, const char *);
*************** fortran_common (tree decl, HOST_WIDE_INT
*** 16137,16144 ****
     since we will need to refer to them each time the function is inlined.  */
  
  static bool
! add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool 
cache_p,
!                                      enum dwarf_attribute attr)
  {
    rtx rtl;
    dw_loc_list_ref list;
--- 16136,16142 ----
     since we will need to refer to them each time the function is inlined.  */
  
  static bool
! add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool 
cache_p)
  {
    rtx rtl;
    dw_loc_list_ref list;
*************** add_location_or_const_value_attribute (d
*** 16151,16157 ****
    if (TREE_CODE (decl) == ERROR_MARK)
      return false;
  
!   if (get_AT (die, attr))
      return true;
  
    gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL
--- 16149,16156 ----
    if (TREE_CODE (decl) == ERROR_MARK)
      return false;
  
!   if (get_AT (die, DW_AT_location)
!       || get_AT (die, DW_AT_const_value))
      return true;
  
    gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL
*************** add_location_or_const_value_attribute (d
*** 16217,16223 ****
      }
    if (list)
      {
!       add_AT_location_description (die, attr, list);
        return true;
      }
    /* None of that worked, so it must not really have a location;
--- 16216,16222 ----
      }
    if (list)
      {
!       add_AT_location_description (die, DW_AT_location, list);
        return true;
      }
    /* None of that worked, so it must not really have a location;
*************** gen_formal_parameter_die (tree node, tre
*** 18117,18123 ****
          equate_decl_number_to_die (node, parm_die);
        if (! DECL_ABSTRACT_P (node_or_origin))
        add_location_or_const_value_attribute (parm_die, node_or_origin,
!                                              node == NULL, DW_AT_location);
  
        break;
  
--- 18116,18122 ----
          equate_decl_number_to_die (node, parm_die);
        if (! DECL_ABSTRACT_P (node_or_origin))
        add_location_or_const_value_attribute (parm_die, node_or_origin,
!                                              node == NULL);
  
        break;
  
*************** gen_variable_die (tree decl, tree origin
*** 19663,19669 ****
        add_pubname (decl_or_origin, var_die);
        else
        add_location_or_const_value_attribute (var_die, decl_or_origin,
!                                              decl == NULL, DW_AT_location);
      }
    else
      tree_add_const_value_attribute_for_decl (var_die, decl_or_origin);
--- 19662,19668 ----
        add_pubname (decl_or_origin, var_die);
        else
        add_location_or_const_value_attribute (var_die, decl_or_origin,
!                                              decl == NULL);
      }
    else
      tree_add_const_value_attribute_for_decl (var_die, decl_or_origin);
*************** dwarf2out_late_global_decl (tree decl)
*** 21640,21647 ****
      {
        dw_die_ref die = lookup_decl_die (decl);
        if (die)
!       add_location_or_const_value_attribute (die, decl, false,
!                                              DW_AT_location);
      }
  }
  
--- 21639,21645 ----
      {
        dw_die_ref die = lookup_decl_die (decl);
        if (die)
!       add_location_or_const_value_attribute (die, decl, false);
      }
  }
  
Index: gcc/testsuite/g++.dg/debug/dwarf2/pr67764.C
===================================================================
*** gcc/testsuite/g++.dg/debug/dwarf2/pr67764.C (revision 0)
--- gcc/testsuite/g++.dg/debug/dwarf2/pr67764.C (working copy)
***************
*** 0 ****
--- 1,17 ----
+ // PR debug/67664
+ // { dg-do compile }
+ // { dg-options "-gdwarf-2 -dA" }
+ 
+ struct T
+ {
+   static const int a = 0;
+ };
+ 
+ int main()
+ {
+   T t;
+   return t.a;
+ }
+ 
+ // Once for the value and once for the abbrev
+ // { dg-final { scan-assembler-times "DW_AT_const_value" 2 } }

Reply via email to