]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport PRs 53685, 56968, 57022
authorJanus Weil <janus@gcc.gnu.org>
Fri, 26 Apr 2013 22:26:02 +0000 (00:26 +0200)
committerJanus Weil <janus@gcc.gnu.org>
Fri, 26 Apr 2013 22:26:02 +0000 (00:26 +0200)
2013-04-26  Janus Weil  <janus@gcc.gnu.org>

Backports from trunk:

PR fortran/56968
* expr.c (gfc_check_pointer_assign): Handle generic functions returning
procedure pointers.

PR fortran/53685
PR fortran/57022
* check.c (gfc_calculate_transfer_sizes): Fix for array-valued SOURCE
expressions.
* target-memory.h (gfc_element_size): New prototype.
* target-memory.c (size_array): Remove.
(gfc_element_size): New function.
(gfc_target_expr_size): Modified to always return the full size of the
expression.

2013-04-26  Janus Weil  <janus@gcc.gnu.org>

Backports from trunk:

PR fortran/56968
* gfortran.dg/proc_ptr_41.f90: New.

PR fortran/53685
PR fortran/57022
* gfortran.dg/transfer_check_4.f90: New.

From-SVN: r198348

gcc/fortran/ChangeLog
gcc/fortran/check.c
gcc/fortran/expr.c
gcc/fortran/target-memory.c
gcc/fortran/target-memory.h
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/proc_ptr_41.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/transfer_check_4.f90 [new file with mode: 0644]

index 13e251a317054494ae8746768ac1900508e52a63..af2c5dc6d045b6eeb29edf7820132ff97e9eb894 100644 (file)
@@ -1,3 +1,21 @@
+2013-04-26  Janus Weil  <janus@gcc.gnu.org>
+
+       Backports from trunk:
+
+       PR fortran/56968
+       * expr.c (gfc_check_pointer_assign): Handle generic functions returning
+       procedure pointers.
+
+       PR fortran/53685
+       PR fortran/57022
+       * check.c (gfc_calculate_transfer_sizes): Fix for array-valued SOURCE
+       expressions.
+       * target-memory.h (gfc_element_size): New prototype.
+       * target-memory.c (size_array): Remove.
+       (gfc_element_size): New function.
+       (gfc_target_expr_size): Modified to always return the full size of the
+       expression.
+
 2013-04-18  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/56994
index d69ba886373818f0cc05f54afffb80c605ee39f3..f6195aa8b3a04c75241343040815f07f2ed845fb 100644 (file)
@@ -3988,8 +3988,6 @@ gfc_calculate_transfer_sizes (gfc_expr *source, gfc_expr *mold, gfc_expr *size,
                              size_t *result_length_p)
 {
   size_t result_elt_size;
-  mpz_t tmp;
-  gfc_expr *mold_element;
 
   if (source->expr_type == EXPR_FUNCTION)
     return FAILURE;
@@ -3998,20 +3996,12 @@ gfc_calculate_transfer_sizes (gfc_expr *source, gfc_expr *mold, gfc_expr *size,
     return FAILURE;
 
   /* Calculate the size of the source.  */
-  if (source->expr_type == EXPR_ARRAY
-      && gfc_array_size (source, &tmp) == FAILURE)
-    return FAILURE;
-
   *source_size = gfc_target_expr_size (source);
   if (*source_size == 0)
     return FAILURE;
 
-  mold_element = mold->expr_type == EXPR_ARRAY
-                ? gfc_constructor_first (mold->value.constructor)->expr
-                : mold;
-
   /* Determine the size of the element.  */
-  result_elt_size = gfc_target_expr_size (mold_element);
+  result_elt_size = gfc_element_size (mold);
   if (result_elt_size == 0)
     return FAILURE;
 
index 0ad7f7b5b9ee4b40656319993fc506e4fa98a9a0..194deb6fb2b1bd86709310e03abc7f1d291a7d92 100644 (file)
@@ -3493,8 +3493,12 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
        }
       else if (rvalue->expr_type == EXPR_FUNCTION)
        {
-         s2 = rvalue->symtree->n.sym->result;
-         name = rvalue->symtree->n.sym->result->name;
+         if (rvalue->value.function.esym)
+           s2 = rvalue->value.function.esym->result;
+         else
+           s2 = rvalue->symtree->n.sym->result;
+
+         name = s2->name;
        }
       else
        {
index 213ee52d307f199538fee433a051d28b1c378550..077c829bac71b3ef2c8256fab8b48c3866f8fcbf 100644 (file)
@@ -35,16 +35,6 @@ along with GCC; see the file COPYING3.  If not see
 /* --------------------------------------------------------------- */ 
 /* Calculate the size of an expression.  */
 
-static size_t
-size_array (gfc_expr *e)
-{
-  mpz_t array_size;
-  gfc_constructor *c = gfc_constructor_first (e->value.constructor);
-  size_t elt_size = gfc_target_expr_size (c->expr);
-
-  gfc_array_size (e, &array_size);
-  return (size_t)mpz_get_ui (array_size) * elt_size;
-}
 
 static size_t
 size_integer (int kind)
@@ -82,16 +72,14 @@ size_character (int length, int kind)
 }
 
 
+/* Return the size of a single element of the given expression.
+   Identical to gfc_target_expr_size for scalars.  */
+
 size_t
-gfc_target_expr_size (gfc_expr *e)
+gfc_element_size (gfc_expr *e)
 {
   tree type;
 
-  gcc_assert (e != NULL);
-
-  if (e->expr_type == EXPR_ARRAY)
-    return size_array (e);
-
   switch (e->ts.type)
     {
     case BT_INTEGER:
@@ -130,12 +118,36 @@ gfc_target_expr_size (gfc_expr *e)
        return int_size_in_bytes (type);
       }
     default:
-      gfc_internal_error ("Invalid expression in gfc_target_expr_size.");
+      gfc_internal_error ("Invalid expression in gfc_element_size.");
       return 0;
     }
 }
 
 
+/* Return the size of an expression in its target representation.  */
+
+size_t
+gfc_target_expr_size (gfc_expr *e)
+{
+  mpz_t tmp;
+  size_t asz;
+
+  gcc_assert (e != NULL);
+
+  if (e->rank)
+    {
+      if (gfc_array_size (e, &tmp))
+       asz = mpz_get_ui (tmp);
+      else
+       asz = 0;
+    }
+  else
+    asz = 1;
+
+  return asz * gfc_element_size (e);
+}
+
+
 /* The encode_* functions export a value into a buffer, and 
    return the number of bytes of the buffer that have been
    used.  */
index 6ebffe86521eece12610b96149044f9bb893d44e..660ab8083d9e30d32c57dd1cf9667f07359b592b 100644 (file)
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 /* Convert a BOZ to REAL or COMPLEX.  */
 bool gfc_convert_boz (gfc_expr *, gfc_typespec *);
 
-/* Return the size of an expression in its target representation.  */
+size_t gfc_element_size (gfc_expr *);
 size_t gfc_target_expr_size (gfc_expr *);
 
 /* Write a constant expression in binary form to a target buffer.  */
index a719d45e8f4a9701c3f4eea5213c00ac648deedb..0da9878892d4cc94496965526e0f93dfc198279a 100644 (file)
@@ -1,3 +1,14 @@
+2013-04-26  Janus Weil  <janus@gcc.gnu.org>
+
+       Backports from trunk:
+
+       PR fortran/56968
+       * gfortran.dg/proc_ptr_41.f90: New.
+
+       PR fortran/53685
+       PR fortran/57022
+       * gfortran.dg/transfer_check_4.f90: New.
+
 2013-04-19  Marek Polacek  <polacek@redhat.com>
 
        Backport from mainline
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_41.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_41.f90
new file mode 100644 (file)
index 0000000..7f50aba
--- /dev/null
@@ -0,0 +1,37 @@
+! { dg-do compile }
+!
+! PR 56968: [4.7/4.8/4.9 Regression] [F03] Issue with a procedure defined with a generic name returning procedure pointer
+!
+! Contributed by Samuel Debionne <samuel.debionne@ujf-grenoble.fr>
+
+module test
+
+  interface generic_name_get_proc_ptr
+    module procedure specific_name_get_proc_ptr
+  end interface
+
+  abstract interface
+    double precision function foo(arg1)
+      real, intent(in) :: arg1
+    end function
+  end interface
+
+contains
+
+  function specific_name_get_proc_ptr() result(res)
+    procedure(foo), pointer :: res
+  end function
+
+end module test
+
+program crash_test
+    use :: test
+
+    procedure(foo), pointer :: ptr
+
+    ptr => specific_name_get_proc_ptr()
+    ptr => generic_name_get_proc_ptr()
+
+end program
+
+! { dg-final { cleanup-modules "test" } }
diff --git a/gcc/testsuite/gfortran.dg/transfer_check_4.f90 b/gcc/testsuite/gfortran.dg/transfer_check_4.f90
new file mode 100644 (file)
index 0000000..030d345
--- /dev/null
@@ -0,0 +1,44 @@
+! { dg-do compile }
+! { dg-options "-Wall" }
+
+! PR 57022: [4.7/4.8/4.9 Regression] Inappropriate warning for use of TRANSFER with arrays
+! Contributed by William Clodius <wclodius@los-alamos.net>
+
+subroutine transfers (test)
+
+  use, intrinsic :: iso_fortran_env
+  
+  integer, intent(in) :: test
+
+  integer(int8)  :: test8(8)  = 0
+  integer(int16) :: test16(4) = 0
+  integer(int32) :: test32(2) = 0
+  integer(int64) :: test64    = 0
+
+  select case(test)
+  case(0)
+    test64 = transfer(test8, test64)
+  case(1)
+    test64 = transfer(test16, test64)
+  case(2)
+    test64 = transfer(test32, test64)
+  case(3)
+    test8  = transfer(test64, test8, 8)
+  case(4)
+    test16 = transfer(test64, test16, 4)
+  case(5)
+    test32 = transfer(test64, test32, 2)
+  end select
+
+end subroutine
+
+
+! PR 53685: surprising warns about transfer with explicit character range
+! Contributed by Jos de Kloe <kloedej@knmi.nl>
+
+subroutine mytest(byte_array,val)
+  integer, parameter :: r8_ = Selected_Real_Kind(15,307)  ! = real*8
+  character(len=1), dimension(16), intent(in) :: byte_array
+  real(r8_),intent(out) :: val
+  val = transfer(byte_array(1:8),val)    
+end subroutine