Hello,

This is a simple patch that fixes PR 4755. Currently the ALLOCATE statement will free and re-allocate an already allocated scalar. The Fortran standard says that this is an error. The attached patch fixes the problem.

I am also attaching two tree dumps of the same program, compiled before and after the application of this patch. The test program is this:

program test
    integer, allocatable :: A(:), B[:]
    integer :: stat
    character(len=33) :: str
    allocate(A(1), B[*], stat=stat)
end program


If you compare the "before" and "after" files you'll see that with this patch GCC no longer tries to free and reallocate A(1). You will also notice that the block for B[*] didn't change. The block for B[*] is already correct in trunk and doesn't need changing.

Here is my ChangeLog:


2011-07-22  Daniel Carrera  <dcarr...@gmail.com>

        * trans.c (gfc__allocate_allocatable): [PR 4755] Do not fix
        and the reallocate a variable that is already allocated.
--
I'm not overweight, I'm undertall.
diff -r c8b6eb02738a gcc/fortran/trans.c
--- a/gcc/fortran/trans.c	Fri Jul 22 09:21:49 2011 +0000
+++ b/gcc/fortran/trans.c	Fri Jul 22 20:36:23 2011 +0200
@@ -775,13 +775,8 @@ gfc_allocate_allocatable (stmtblock_t * 
       stmtblock_t set_status_block;
 
       gfc_start_block (&set_status_block);
-      tmp = build_call_expr_loc (input_location,
-			     built_in_decls[BUILT_IN_FREE], 1,
-			     fold_convert (pvoid_type_node, mem));
-      gfc_add_expr_to_block (&set_status_block, tmp);
 
-      tmp = gfc_allocate_using_malloc (&set_status_block, size, status);
-      gfc_add_modify (&set_status_block, res, fold_convert (type, tmp));
+      gfc_add_modify (&set_status_block, res, fold_convert (type, mem));
 
       gfc_add_modify (&set_status_block, status,
 		      build_int_cst (status_type, LIBERROR_ALLOCATION));
test ()
{
  struct array1_integer(kind=4) a;
  struct array1_integer(kind=4) b;
  integer(kind=4) stat;

  try
    {
      a.data = 0B;
      b.data = 0B;
      {
        integer(kind=4) overflow.1;
        integer(kind=4) D.1537;
        integer(kind=4) D.1536;
        integer(kind=4) stat.0;

        a.dtype = 265;
        a.dim[0].lbound = 1;
        a.dim[0].ubound = 1;
        a.dim[0].stride = 1;
        D.1536 = (logical(kind=4)) 0 ? 0 : (logical(kind=4)) 0 ? 1 : 0;
        D.1537 = ((logical(kind=4)) 0 ? 0 : (logical(kind=4)) 0 ? 1 : 0) + 
D.1536;
        overflow.1 = D.1537;
        if ((logical(kind=4)) __builtin_expect ((<unnamed-signed:32>) 
(overflow.1 != 0), 0))
          {
            stat.0 = 5014;
          }
        else
          {
            {
              void * restrict D.1539;

              if ((logical(kind=4)) __builtin_expect ((<unnamed-signed:32>) 
(a.data != 0B), 0))
                {
                  D.1539 = a.data;
                  stat.0 = 5014;
                }
              else
                {
                  {
                    void * restrict D.1540;

                    stat.0 = 0;
                    D.1540 = (void * restrict) __builtin_malloc (4);
                    if (D.1540 == 0B)
                      {
                        stat.0 = 5014;
                      }
                    D.1539 = D.1540;
                  }
                }
              a.data = D.1539;
            }
          }
        a.offset = -1;
        if (stat.0 != 0) goto L.1;
        b.dtype = 264;
        b.dim[0].lbound = 1;
        {
          void * restrict D.1541;

          if ((logical(kind=4)) __builtin_expect ((<unnamed-signed:32>) (b.data 
!= 0B), 0))
            {
              D.1541 = b.data;
              stat.0 = 5014;
            }
          else
            {
              {
                void * restrict D.1542;

                D.1542 = (void * restrict) _gfortran_caf_register (4, 1, 0B, 
&stat.0, 0B, 0);
                D.1541 = D.1542;
              }
            }
          b.data = D.1541;
        }
        if (stat.0 != 0) goto L.2;
        L.1:;
        L.2:;
        stat = stat.0;
      }
    }
  finally
    {
      if (b.data != 0B)
        {
          __builtin_free ((void *) b.data);
        }
      b.data = 0B;
      if (a.data != 0B)
        {
          __builtin_free ((void *) a.data);
        }
      a.data = 0B;
    }
}


main (integer(kind=4) argc, character(kind=1) * * argv)
{
  static integer(kind=4) options.2[8] = {68, 1023, 0, 0, 1, 1, 0, 1};

  _gfortran_caf_init (&argc, &argv, &_gfortran_caf_this_image, 
&_gfortran_caf_num_images);
  _gfortran_set_args (argc, argv);
  _gfortran_set_options (8, &options.2[0]);
  test ();
  __sync_synchronize ();
  _gfortran_caf_finalize ();
  return 0;
}


test ()
{
  struct array1_integer(kind=4) a;
  struct array1_integer(kind=4) b;
  integer(kind=4) stat;

  try
    {
      a.data = 0B;
      b.data = 0B;
      {
        integer(kind=4) overflow.1;
        integer(kind=4) D.1537;
        integer(kind=4) D.1536;
        integer(kind=4) stat.0;

        a.dtype = 265;
        a.dim[0].lbound = 1;
        a.dim[0].ubound = 1;
        a.dim[0].stride = 1;
        D.1536 = (logical(kind=4)) 0 ? 0 : (logical(kind=4)) 0 ? 1 : 0;
        D.1537 = ((logical(kind=4)) 0 ? 0 : (logical(kind=4)) 0 ? 1 : 0) + 
D.1536;
        overflow.1 = D.1537;
        if ((logical(kind=4)) __builtin_expect ((<unnamed-signed:32>) 
(overflow.1 != 0), 0))
          {
            stat.0 = 5014;
          }
        else
          {
            {
              void * restrict D.1539;

              if ((logical(kind=4)) __builtin_expect ((<unnamed-signed:32>) 
(a.data != 0B), 0))
                {
                  {
                    void * restrict D.1541;

                    __builtin_free ((void *) a.data);
                    stat.0 = 0;
                    D.1541 = (void * restrict) __builtin_malloc (4);
                    if (D.1541 == 0B)
                      {
                        stat.0 = 5014;
                      }
                    D.1539 = D.1541;
                    stat.0 = 5014;
                  }
                }
              else
                {
                  {
                    void * restrict D.1540;

                    stat.0 = 0;
                    D.1540 = (void * restrict) __builtin_malloc (4);
                    if (D.1540 == 0B)
                      {
                        stat.0 = 5014;
                      }
                    D.1539 = D.1540;
                  }
                }
              a.data = D.1539;
            }
          }
        a.offset = -1;
        if (stat.0 != 0) goto L.1;
        b.dtype = 264;
        b.dim[0].lbound = 1;
        {
          void * restrict D.1542;

          if ((logical(kind=4)) __builtin_expect ((<unnamed-signed:32>) (b.data 
!= 0B), 0))
            {
              {
                void * restrict D.1544;

                __builtin_free ((void *) b.data);
                stat.0 = 0;
                D.1544 = (void * restrict) __builtin_malloc (4);
                if (D.1544 == 0B)
                  {
                    stat.0 = 5014;
                  }
                D.1542 = D.1544;
                stat.0 = 5014;
              }
            }
          else
            {
              {
                void * restrict D.1543;

                D.1543 = (void * restrict) _gfortran_caf_register (4, 1, 0B, 
&stat.0, 0B, 0);
                D.1542 = D.1543;
              }
            }
          b.data = D.1542;
        }
        if (stat.0 != 0) goto L.2;
        L.1:;
        L.2:;
        stat = stat.0;
      }
    }
  finally
    {
      if (b.data != 0B)
        {
          __builtin_free ((void *) b.data);
        }
      b.data = 0B;
      if (a.data != 0B)
        {
          __builtin_free ((void *) a.data);
        }
      a.data = 0B;
    }
}


main (integer(kind=4) argc, character(kind=1) * * argv)
{
  static integer(kind=4) options.2[8] = {68, 1023, 0, 0, 1, 1, 0, 1};

  _gfortran_caf_init (&argc, &argv, &_gfortran_caf_this_image, 
&_gfortran_caf_num_images);
  _gfortran_set_args (argc, argv);
  _gfortran_set_options (8, &options.2[0]);
  test ();
  __sync_synchronize ();
  _gfortran_caf_finalize ();
  return 0;
}


Reply via email to