This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug other/63504] [5 Regression] Issues found by --enable-checking=valgrind


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63504

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ccoutant at gcc dot gnu.org,
                   |                            |mrs at gcc dot gnu.org

--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The 1) issue is that e.g.
  mem_loc_result->dw_loc_oprnd2.v.val_wide = ggc_cleared_alloc<wide_int> ();
  *mem_loc_result->dw_loc_oprnd2.v.val_wide = std::make_pair (rtl, mode);
doesn't in any way make sure the unused bits in the structure are all zeros,
they can contain random stack garbage.  While the object is allocated cleared,
then it is overwritten with bits from wide_int constructed.

So I think we want something like:

--- gcc/dwarf2out.c.jj    2015-01-27 19:03:30.000000000 +0100
+++ gcc/dwarf2out.c    2015-01-27 20:10:27.683868052 +0100
@@ -3886,7 +3886,7 @@ add_AT_wide (dw_die_ref die, enum dwarf_

   attr.dw_attr = attr_kind;
   attr.dw_attr_val.val_class = dw_val_class_wide_int;
-  attr.dw_attr_val.v.val_wide = ggc_cleared_alloc<wide_int> ();
+  attr.dw_attr_val.v.val_wide = ggc_alloc<wide_int> ();
   *attr.dw_attr_val.v.val_wide = w;
   add_dwarf_attr (die, &attr);
 }
@@ -5728,7 +5728,14 @@ attr_checksum (dw_attr_ref at, struct md
       CHECKSUM (at->dw_attr_val.v.val_double);
       break;
     case dw_val_class_wide_int:
-      CHECKSUM (*at->dw_attr_val.v.val_wide);
+      {
+        unsigned int len = at->dw_attr_val.v.val_wide->get_len ();
+        unsigned int precision = at->dw_attr_val.v.val_wide->get_precision ();
+        CHECKSUM (len);
+        CHECKSUM (precision);
+        CHECKSUM_BLOCK (at->dw_attr_val.v.val_wide->get_val (),
+            HOST_BITS_PER_WIDE_INT * len / HOST_BITS_PER_CHAR);
+      }
       break;
     case dw_val_class_vec:
       CHECKSUM_BLOCK (at->dw_attr_val.v.val_vec.array,
@@ -13162,7 +13169,7 @@ mem_loc_descriptor (rtx rtl, machine_mod
       mem_loc_result->dw_loc_oprnd1.v.val_die_ref.external = 0;
       mem_loc_result->dw_loc_oprnd2.val_class
         = dw_val_class_wide_int;
-      mem_loc_result->dw_loc_oprnd2.v.val_wide = ggc_cleared_alloc<wide_int>
();
+      mem_loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc<wide_int> ();
       *mem_loc_result->dw_loc_oprnd2.v.val_wide = std::make_pair (rtl, mode);
     }
       break;
@@ -13665,7 +13672,7 @@ loc_descriptor (rtx rtl, machine_mode mo
       loc_result = new_loc_descr (DW_OP_implicit_value,
                       GET_MODE_SIZE (mode), 0);
       loc_result->dw_loc_oprnd2.val_class = dw_val_class_wide_int;
-      loc_result->dw_loc_oprnd2.v.val_wide = ggc_cleared_alloc<wide_int> ();
+      loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc<wide_int> ();
       *loc_result->dw_loc_oprnd2.v.val_wide = std::make_pair (rtl, mode);
     }
       break;
@@ -24037,7 +24044,14 @@ hash_loc_operands (dw_loc_descr_ref loc,
       hstate.add_object (val2->v.val_double.high);
       break;
     case dw_val_class_wide_int:
-      hstate.add_object (*val2->v.val_wide);
+      {
+        unsigned int precision = val2->v.val_wide->get_precision ();
+        unsigned int len = val2->v.val_wide->get_len ();
+        hstate.add_object (precision);
+        hstate.add_object (len);
+        hstate.add (val2->v.val_wide->get_val (),
+            HOST_BITS_PER_WIDE_INT * len / HOST_BITS_PER_CHAR);
+      }
       break;
     case dw_val_class_addr:    
       inchash::add_rtx (val2->v.val_addr, hstate);
@@ -24128,7 +24142,14 @@ hash_loc_operands (dw_loc_descr_ref loc,
         hstate.add_object (val2->v.val_double.high);
         break;
       case dw_val_class_wide_int:
-        hstate.add_object (*val2->v.val_wide);
+        {
+          unsigned int precision = val2->v.val_wide->get_precision ();
+          unsigned int len = val2->v.val_wide->get_len ();
+          hstate.add_object (precision);
+          hstate.add_object (len);
+          hstate.add (val2->v.val_wide->get_val (),
+              HOST_BITS_PER_WIDE_INT * len / HOST_BITS_PER_CHAR);
+        }
         break;
       default:
         gcc_unreachable ();

or perhaps not hash precision and len separately, but instead call get_full_len
to get that length and use that for the get_val () checksumming?

But then there is (question mainly on Cary) the .debug_types checksumming:

    case dw_val_class_const_double:
      CHECKSUM_ULEB128 (DW_FORM_block);
      CHECKSUM_ULEB128 (sizeof (at->dw_attr_val.v.val_double));
      CHECKSUM (at->dw_attr_val.v.val_double);
      break;

    case dw_val_class_wide_int:
      CHECKSUM_ULEB128 (DW_FORM_block);
      CHECKSUM_ULEB128 (sizeof (*at->dw_attr_val.v.val_wide));
      CHECKSUM (*at->dw_attr_val.v.val_wide);
      break;

and that one ought to be governed by the DWARF standard, so I wonder how it can
get away without converting for endianity etc.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]