As mentioned in the PR, gcc has a new warning about size calculations of
arrays ([-Wsizeof-array-div]), which fired in libgfortran/intrinsics/random.c,
and complained about the macro SZ that determines the size of the internal
state of the random number generator for different integer kinds.

A fix is trivial.  The attached patch was basically discussed in the PR
with David, and regtests cleanly.

I'll give others 72 hours to comment or complain, otherwise I'll commit as
obvious to master.

Thanks,
Harald


PR libgfortran/97581 - clean up size calculation of random generator state

The random number generator internal state may be saved to/restored from
an array of integers.  Clean up calculation of needed number of elements
to avoid redefiniton of auxiliary macro SZ.

libgfortran/ChangeLog:

        * intrinsics/random.c (SZ_IN_INT_4): Define size of state in in32_t.
        (SZ_IN_INT_8): Define size of state in in64_t.
        (SZ): Remove.
        (random_seed_i4): Use size SZ_IN_INT_4 instead of SZ.
        (random_seed_i8): Use size SZ_IN_INT_8 instead of SZ.

diff --git a/libgfortran/intrinsics/random.c b/libgfortran/intrinsics/random.c
index af8b1bc891b..a864ab9f1fd 100644
--- a/libgfortran/intrinsics/random.c
+++ b/libgfortran/intrinsics/random.c
@@ -723,6 +723,9 @@ arandom_r16 (gfc_array_r16 *x)
 /* Number of elements in master_state array.  */
 #define SZU64 (sizeof (master_state.s) / sizeof (uint64_t))

+/* Equivalent number of elements in an array of GFC_INTEGER_{4,8}.  */
+#define SZ_IN_INT_4 (SZU64 * (sizeof (uint64_t) / sizeof (GFC_INTEGER_4)))
+#define SZ_IN_INT_8 (SZU64 * (sizeof (uint64_t) / sizeof (GFC_INTEGER_8)))

 /* Keys for scrambling the seed in order to avoid poor seeds.  */

@@ -751,14 +754,13 @@ void
 random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
 {
   uint64_t seed[SZU64];
-#define SZ (sizeof (master_state.s) / sizeof (GFC_INTEGER_4))

   /* Check that we only have one argument present.  */
   if ((size ? 1 : 0) + (put ? 1 : 0) + (get ? 1 : 0) > 1)
     runtime_error ("RANDOM_SEED should have at most one argument present.");

   if (size != NULL)
-    *size = SZ;
+    *size = SZ_IN_INT_4;

   prng_state* rs = get_rand_state();

@@ -770,7 +772,7 @@ random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
 	runtime_error ("Array rank of GET is not 1.");

       /* If the array is too small, abort.  */
-      if (GFC_DESCRIPTOR_EXTENT(get,0) < (index_type) SZ)
+      if (GFC_DESCRIPTOR_EXTENT(get,0) < (index_type) SZ_IN_INT_4)
 	runtime_error ("Array size of GET is too small.");

       if (!rs->init)
@@ -780,8 +782,9 @@ random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
       scramble_seed (seed, rs->s);

       /*  Then copy it back to the user variable.  */
-      for (size_t i = 0; i < SZ ; i++)
-	memcpy (&(get->base_addr[(SZ - 1 - i) * GFC_DESCRIPTOR_STRIDE(get,0)]),
+      for (size_t i = 0; i < SZ_IN_INT_4 ; i++)
+	memcpy (&(get->base_addr[(SZ_IN_INT_4 - 1 - i) *
+				 GFC_DESCRIPTOR_STRIDE(get,0)]),
 		(unsigned char*) seed + i * sizeof(GFC_UINTEGER_4),
                sizeof(GFC_UINTEGER_4));
     }
@@ -805,13 +808,14 @@ random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
         runtime_error ("Array rank of PUT is not 1.");

       /* If the array is too small, abort.  */
-      if (GFC_DESCRIPTOR_EXTENT(put,0) < (index_type) SZ)
+      if (GFC_DESCRIPTOR_EXTENT(put,0) < (index_type) SZ_IN_INT_4)
         runtime_error ("Array size of PUT is too small.");

       /*  We copy the seed given by the user.  */
-      for (size_t i = 0; i < SZ; i++)
+      for (size_t i = 0; i < SZ_IN_INT_4; i++)
 	memcpy ((unsigned char*) seed + i * sizeof(GFC_UINTEGER_4),
-		&(put->base_addr[(SZ - 1 - i) * GFC_DESCRIPTOR_STRIDE(put,0)]),
+		&(put->base_addr[(SZ_IN_INT_4 - 1 - i) *
+				 GFC_DESCRIPTOR_STRIDE(put,0)]),
 		sizeof(GFC_UINTEGER_4));

       /* We put it after scrambling the bytes, to paper around users who
@@ -823,7 +827,6 @@ random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)

   __gthread_mutex_unlock (&random_lock);
     }
-#undef SZ
 }
 iexport(random_seed_i4);

@@ -837,9 +840,8 @@ random_seed_i8 (GFC_INTEGER_8 *size, gfc_array_i8 *put, gfc_array_i8 *get)
   if ((size ? 1 : 0) + (put ? 1 : 0) + (get ? 1 : 0) > 1)
     runtime_error ("RANDOM_SEED should have at most one argument present.");

-#define SZ (sizeof (master_state.s) / sizeof (GFC_INTEGER_8))
   if (size != NULL)
-    *size = SZ;
+    *size = SZ_IN_INT_8;

   prng_state* rs = get_rand_state();

@@ -851,7 +853,7 @@ random_seed_i8 (GFC_INTEGER_8 *size, gfc_array_i8 *put, gfc_array_i8 *get)
 	runtime_error ("Array rank of GET is not 1.");

       /* If the array is too small, abort.  */
-      if (GFC_DESCRIPTOR_EXTENT(get,0) < (index_type) SZ)
+      if (GFC_DESCRIPTOR_EXTENT(get,0) < (index_type) SZ_IN_INT_8)
 	runtime_error ("Array size of GET is too small.");

       if (!rs->init)
@@ -861,7 +863,7 @@ random_seed_i8 (GFC_INTEGER_8 *size, gfc_array_i8 *put, gfc_array_i8 *get)
       scramble_seed (seed, rs->s);

       /*  This code now should do correct strides.  */
-      for (size_t i = 0; i < SZ; i++)
+      for (size_t i = 0; i < SZ_IN_INT_8; i++)
 	memcpy (&(get->base_addr[i * GFC_DESCRIPTOR_STRIDE(get,0)]), &seed[i],
 		sizeof (GFC_UINTEGER_8));
     }
@@ -885,11 +887,11 @@ random_seed_i8 (GFC_INTEGER_8 *size, gfc_array_i8 *put, gfc_array_i8 *get)
         runtime_error ("Array rank of PUT is not 1.");

       /* If the array is too small, abort.  */
-      if (GFC_DESCRIPTOR_EXTENT(put,0) < (index_type) SZ)
+      if (GFC_DESCRIPTOR_EXTENT(put,0) < (index_type) SZ_IN_INT_8)
         runtime_error ("Array size of PUT is too small.");

       /*  This code now should do correct strides.  */
-      for (size_t i = 0; i < SZ; i++)
+      for (size_t i = 0; i < SZ_IN_INT_8; i++)
 	memcpy (&seed[i], &(put->base_addr[i * GFC_DESCRIPTOR_STRIDE(put,0)]),
 		sizeof (GFC_UINTEGER_8));

Reply via email to