PR middle-end/56461
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Mar 2013 15:51:48 +0000 (15:51 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Mar 2013 15:51:48 +0000 (15:51 +0000)
* ggc-common.c (gt_pch_save): For ENABLE_VALGRIND_CHECKING,
if VALGRIND_GET_VBITS is defined, temporarily make object
memory all defined, and restore previous valgrind addressability
and definability afterwards.  Free this_object at the end.

* c-pch.c (pch_init): Free target_validity at the end.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@196469 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-pch.c
gcc/ggc-common.c

index 4734403..4c0744f 100644 (file)
@@ -1,6 +1,12 @@
 2013-03-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/56461
+       * ggc-common.c (gt_pch_save): For ENABLE_VALGRIND_CHECKING,
+       if VALGRIND_GET_VBITS is defined, temporarily make object
+       memory all defined, and restore previous valgrind addressability
+       and definability afterwards.  Free this_object at the end.
+
+       PR middle-end/56461
        * lra.c (lra): Call lra_clear_live_ranges if live_p,
        right before calling lra_create_live_ranges, also call it
        when clearing live_p.  Only call lra_clear_live_ranges
index b8ca5ae..6d90bfb 100644 (file)
@@ -1,3 +1,8 @@
+2013-03-05  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/56461
+       * c-pch.c (pch_init): Free target_validity at the end.
+
 2013-03-04  Jakub Jelinek  <jakub@redhat.com>
 
        * c-pretty-print.c (pp_c_pretty_printer_init): Clear pp->flags.
index c40ee8d..7b0eca7 100644 (file)
@@ -141,6 +141,8 @@ pch_init (void)
 
   if (pch_ready_to_save_cpp_state)
     pch_cpp_save_state ();
+
+  XDELETE (target_validity);
 }
 
 /* Whether preprocessor state has been saved in a PCH file.  */
index f02224a..91c8249 100644 (file)
@@ -561,6 +561,10 @@ gt_pch_save (FILE *f)
 
   ggc_pch_prepare_write (state.d, state.f);
 
+#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
+  vec<char> vbits = vNULL;
+#endif
+
   /* Actually write out the objects.  */
   for (i = 0; i < state.count; i++)
     {
@@ -569,6 +573,50 @@ gt_pch_save (FILE *f)
          this_object_size = state.ptrs[i]->size;
          this_object = XRESIZEVAR (char, this_object, this_object_size);
        }
+#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
+      /* obj might contain uninitialized bytes, e.g. in the trailing
+        padding of the object.  Avoid warnings by making the memory
+        temporarily defined and then restoring previous state.  */
+      int get_vbits = 0;
+      size_t valid_size = state.ptrs[i]->size;
+      if (__builtin_expect (RUNNING_ON_VALGRIND, 0))
+       {
+         if (vbits.length () < valid_size)
+           vbits.safe_grow (valid_size);
+         get_vbits = VALGRIND_GET_VBITS (state.ptrs[i]->obj,
+                                         vbits.address (), valid_size);
+         if (get_vbits == 3)
+           {
+             /* We assume that first part of obj is addressable, and
+                the rest is unaddressable.  Find out where the boundary is
+                using binary search.  */
+             size_t lo = 0, hi = valid_size;
+             while (hi > lo)
+               {
+                 size_t mid = (lo + hi) / 2;
+                 get_vbits = VALGRIND_GET_VBITS ((char *) state.ptrs[i]->obj
+                                                 + mid, vbits.address (),
+                                                 1);
+                 if (get_vbits == 3)
+                   hi = mid;
+                 else if (get_vbits == 1)
+                   lo = mid + 1;
+                 else
+                   break;
+               }
+             if (get_vbits == 1 || get_vbits == 3)
+               {
+                 valid_size = lo;
+                 get_vbits = VALGRIND_GET_VBITS (state.ptrs[i]->obj,
+                                                 vbits.address (),
+                                                 valid_size);
+               }
+           }
+         if (get_vbits == 1)
+           VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (state.ptrs[i]->obj,
+                                                        state.ptrs[i]->size));
+       }
+#endif
       memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size);
       if (state.ptrs[i]->reorder_fn != NULL)
        state.ptrs[i]->reorder_fn (state.ptrs[i]->obj,
@@ -582,11 +630,29 @@ gt_pch_save (FILE *f)
                            state.ptrs[i]->note_ptr_fn == gt_pch_p_S);
       if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
        memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
+#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
+      if (__builtin_expect (get_vbits == 1, 0))
+       {
+         (void) VALGRIND_SET_VBITS (state.ptrs[i]->obj, vbits.address (),
+                                    valid_size);
+         if (valid_size != state.ptrs[i]->size)
+           VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS ((char *)
+                                                         state.ptrs[i]->obj
+                                                         + valid_size,
+                                                         state.ptrs[i]->size
+                                                         - valid_size));
+       }
+#endif
     }
+#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
+  vbits.release ();
+#endif
+
   ggc_pch_finish (state.d, state.f);
   gt_pch_fixup_stringpool ();
 
-  free (state.ptrs);
+  XDELETE (state.ptrs);
+  XDELETE (this_object);
   htab_delete (saving_htab);
 }