diff mbox

[Fortran] PR fortran/60289 Fixing character array allocation for class(*) type variable

Message ID 20141229141243.668f9935@gmx.de
State New
Headers show

Commit Message

Andre Vehreschild Dec. 29, 2014, 1:12 p.m. UTC
Hi all,

this patches fixes PR60289 for allocating unlimited polymorphic entities
retyping them to a char array. The patch depends on my former patch for pr60255
at:

https://gcc.gnu.org/ml/fortran/2014-12/msg00130.html

because it needs the _len component introduced. I have extend Janus' patch
given in the PR and added a testcase. 

This is the fifth version of the patch, where the previous hasn't gotten any
comments, so I think it is well enough for commit. What do you think?

Bootstraps and regtests ok on x86_64-linux-gnu.

Depends on: https://gcc.gnu.org/ml/fortran/2014-12/msg00130.html

Regards,
	Andre

Comments

Andre Vehreschild Jan. 16, 2015, 11:36 a.m. UTC | #1
*ping*

On Mon, 29 Dec 2014 14:12:43 +0100
Andre Vehreschild <vehre@gmx.de> wrote:

> Hi all,
> 
> this patches fixes PR60289 for allocating unlimited polymorphic entities
> retyping them to a char array. The patch depends on my former patch for
> pr60255 at:
> 
> https://gcc.gnu.org/ml/fortran/2014-12/msg00130.html
> 
> because it needs the _len component introduced. I have extend Janus' patch
> given in the PR and added a testcase. 
> 
> This is the fifth version of the patch, where the previous hasn't gotten any
> comments, so I think it is well enough for commit. What do you think?
> 
> Bootstraps and regtests ok on x86_64-linux-gnu.
> 
> Depends on: https://gcc.gnu.org/ml/fortran/2014-12/msg00130.html
> 
> Regards,
> 	Andre
diff mbox

Patch

diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 05a948b..6038dd5 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -6930,7 +6930,9 @@  resolve_allocate_expr (gfc_expr *e, gfc_code *code)
       goto failure;
     }
 
-  if (code->ext.alloc.ts.type == BT_CHARACTER && !e->ts.deferred)
+  /* Check F08:C632.  */
+  if (code->ext.alloc.ts.type == BT_CHARACTER && !e->ts.deferred
+      && !UNLIMITED_POLY (e))
     {
       int cmp = gfc_dep_compare_expr (e->ts.u.cl->length,
 				      code->ext.alloc.ts.u.cl->length);
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index c560d05..82ecf31 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -5139,8 +5139,15 @@  gfc_trans_allocate (gfc_code * code)
 	      gfc_add_block_to_block (&se.pre, &se_sz.pre);
 	      se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
 	      gfc_add_block_to_block (&se.pre, &se_sz.post);
-	      /* Store the string length.  */
-	      tmp = al->expr->ts.u.cl->backend_decl;
+	      /* Store the string length.  Get the backend_decl of the _len
+		 component for that.  */
+	      if ((expr->symtree->n.sym->ts.type == BT_CLASS
+		  || expr->symtree->n.sym->ts.type == BT_DERIVED)
+		  && expr->ts.u.derived->attr.unlimited_polymorphic)
+		tmp = gfc_class_len_get (gfc_get_symbol_decl (
+					   expr->symtree->n.sym));
+	      else
+		tmp = al->expr->ts.u.cl->backend_decl;
 	      gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
 			      se_sz.expr));
               tmp = TREE_TYPE (gfc_typenode_for_spec (&code->ext.alloc.ts));
diff --git a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_21.f90 b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_21.f90
new file mode 100644
index 0000000..18a66b0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_21.f90
@@ -0,0 +1,57 @@ 
+! { dg-do run }
+! Testing fix for PR fortran/60289
+! Contributed by: Andre Vehreschild <vehre@gmx.de>
+!
+program test
+    implicit none
+
+    class(*), pointer :: P
+    integer :: string_len = 10 *2
+
+    allocate(character(string_len)::P)
+
+    select type(P)
+        type is (character(*))
+            P ="some test string"
+            if (P .ne. "some test string") then
+                call abort ()
+            end if
+            if (len(P) .ne. 20) then
+                call abort ()
+            end if
+            if (len(P) .eq. len("some test string")) then
+                call abort ()
+            end if
+        class default
+            call abort ()
+    end select
+
+    deallocate(P)
+
+    ! Now for kind=4 chars.
+
+    allocate(character(len=20,kind=4)::P)
+
+    select type(P)
+        type is (character(len=*,kind=4))
+            P ="some test string"
+            if (P .ne. 4_"some test string") then
+                call abort ()
+            end if
+            if (len(P) .ne. 20) then
+                call abort ()
+            end if
+            if (len(P) .eq. len("some test string")) then
+                call abort ()
+            end if
+        type is (character(len=*,kind=1))
+            call abort ()
+        class default
+            call abort ()
+    end select
+
+    deallocate(P)
+
+
+end program test
+