Fix '32-bit value shift followed by expansion to 64-bit' code defect
authorIvan Maidanski <ivmai@mail.ru>
Wed, 7 Dec 2016 07:22:09 +0000 (10:22 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Wed, 7 Dec 2016 07:22:09 +0000 (10:22 +0300)
* gcj_mlc.c [GC_GCJ_SUPPORT] (GC_core_gcj_malloc,
GC_gcj_malloc_ignore_off_page): Cast lg local variable to word before
passing it to GRANULES_TO_BYTES (so that value type widening does not
occur after the value left shift).
* malloc.c (GC_generic_malloc_inner, GC_malloc_kind_global,
GC_generic_malloc_uncollectable): Likewise.
* typd_mlc.c (GC_malloc_explicitly_typed_ignore_off_page): Likewise.
* misc.c (block_add_size): Cast hhdr->hb_sz to word before passing it
to WORDS_TO_BYTES; cast HBLKSIZE-1 to word before "~" operation.

gcj_mlc.c
malloc.c
misc.c
typd_mlc.c

index 8b2dad7..7b4ea9d 100644 (file)
--- a/gcj_mlc.c
+++ b/gcj_mlc.c
@@ -177,7 +177,7 @@ static void maybe_finalize(void)
             }
         } else {
             GC_gcjobjfreelist[lg] = obj_link(op);
-            GC_bytes_allocd += GRANULES_TO_BYTES(lg);
+            GC_bytes_allocd += GRANULES_TO_BYTES((word)lg);
         }
         *(void **)op = ptr_to_struct_containing_descr;
         GC_ASSERT(((void **)op)[1] == 0);
@@ -250,7 +250,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t lb,
             }
         } else {
             GC_gcjobjfreelist[lg] = obj_link(op);
-            GC_bytes_allocd += GRANULES_TO_BYTES(lg);
+            GC_bytes_allocd += GRANULES_TO_BYTES((word)lg);
         }
     } else {
         LOCK();
index a6e0333..28b2ac6 100644 (file)
--- a/malloc.c
+++ b/malloc.c
@@ -147,7 +147,7 @@ GC_INNER void * GC_generic_malloc_inner(size_t lb, int k)
         }
         *opp = obj_link(op);
         obj_link(op) = 0;
-        GC_bytes_allocd += GRANULES_TO_BYTES(lg);
+        GC_bytes_allocd += GRANULES_TO_BYTES((word)lg);
     } else {
         op = (ptr_t)GC_alloc_large_and_clear(ADD_SLOP(lb), k, 0);
         if (op != NULL)
@@ -266,7 +266,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_kind_global(size_t lb, int k)
                 *opp = obj_link(op);
                 obj_link(op) = 0;
             }
-            GC_bytes_allocd += GRANULES_TO_BYTES(lg);
+            GC_bytes_allocd += GRANULES_TO_BYTES((word)lg);
             UNLOCK();
             return op;
         }
@@ -316,11 +316,11 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_malloc_uncollectable(
         if (EXPECT(op != NULL, TRUE)) {
             *opp = obj_link(op);
             obj_link(op) = 0;
-            GC_bytes_allocd += GRANULES_TO_BYTES(lg);
+            GC_bytes_allocd += GRANULES_TO_BYTES((word)lg);
             /* Mark bit was already set on free list.  It will be       */
             /* cleared only temporarily during a collection, as a       */
             /* result of the normal free list mark bit clearing.        */
-            GC_non_gc_bytes += GRANULES_TO_BYTES(lg);
+            GC_non_gc_bytes += GRANULES_TO_BYTES((word)lg);
             UNLOCK();
         } else {
             UNLOCK();
diff --git a/misc.c b/misc.c
index 43f0d73..b228dbf 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -2069,8 +2069,8 @@ GC_API void * GC_CALL GC_do_blocking(GC_fn_type fn, void * client_data)
 static void block_add_size(struct hblk *h, word pbytes)
 {
   hdr *hhdr = HDR(h);
-  *(word *)pbytes += (WORDS_TO_BYTES(hhdr->hb_sz) + (HBLKSIZE - 1))
-                        & ~(HBLKSIZE - 1);
+  *(word *)pbytes += (WORDS_TO_BYTES((word)hhdr->hb_sz) + (HBLKSIZE - 1))
+                        & ~(word)(HBLKSIZE - 1);
 }
 
 GC_API size_t GC_CALL GC_get_memory_use(void)
index 7e91fab..7b24a96 100644 (file)
@@ -618,7 +618,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL
         } else {
             GC_eobjfreelist[lg] = obj_link(op);
             obj_link(op) = 0;
-            GC_bytes_allocd += GRANULES_TO_BYTES(lg);
+            GC_bytes_allocd += GRANULES_TO_BYTES((word)lg);
             UNLOCK();
         }
         ((word *)op)[GRANULES_TO_WORDS(lg) - 1] = d;