public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Janus Weil <janus@gcc.gnu.org>
To: Tobias Burnus <burnus@net-b.de>
Cc: gfortran <fortran@gcc.gnu.org>, gcc patches <gcc-patches@gcc.gnu.org>
Subject: Re: [Patch, Fortran, OOP] PR 57306: ICE on valid with class pointer initialization
Date: Tue, 30 Jul 2013 09:11:00 -0000	[thread overview]
Message-ID: <CAKwh3qh9KiNY6BF99m_cy=x=MQZrN_X0p+1idJ=rKSfB=1rhaw@mail.gmail.com> (raw)
In-Reply-To: <CAKwh3qjAXCP0tfmv-JM5BSWH9thrRyVFfPzORTNN-CMr-eyHLg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1606 bytes --]

2013/7/30 Janus Weil <janus@gcc.gnu.org>:
>>> The attached new version should do the right thing now. At least it
>>> shows the correct dump for the original test case as well as yours. It
>>> is currently being regtested.
>>
>> unfortunately it shows a couple of runtime problems with type-bound operators:
>>
>> FAIL: gfortran.dg/class_defined_operator_1.f03  -O0  execution test
>> FAIL: gfortran.dg/typebound_operator_13.f03  -O0  execution test
>> FAIL: gfortran.dg/typebound_operator_7.f03  -O0  execution test
>> FAIL: gfortran.dg/typebound_operator_8.f03  -O0  execution test
>> FAIL: gfortran.dg/typebound_operator_9.f03  -O0  execution test
>
> The attached update fixes it, and thus should hopefully be
> regression-free. It also renames 'gfc_class_null_initializer' to
> 'gfc_class_initializer', since it now also does other initializations
> beside EXPR_NULL.
>
> Will do another regtest to make sure it's clean.

No failures observed. As a test case I'm using now Tobias' extended
version (attached). New ChangeLog below.

Ok for trunk?

Cheers,
Janus


2013-07-30  Janus Weil  <janus@gcc.gnu.org>

    PR fortran/57306
    * class.c (gfc_class_null_initializer): Rename to
    'gfc_class_initializer'. Treat non-NULL init-exprs.
    * gfortran.h (gfc_class_null_initializer): Update prototype.
    * trans-decl.c (gfc_get_symbol_decl): Treat class pointers.
    * trans-expr.c (gfc_conv_initializer): Ditto.
    (gfc_trans_subcomponent_assign): Renamed gfc_class_null_initializer.

2013-07-30  Janus Weil  <janus@gcc.gnu.org>

    PR fortran/57306
    * gfortran.dg/pointer_init_8.f90: New.

[-- Attachment #2: pr57306_v4.diff --]
[-- Type: application/octet-stream, Size: 4699 bytes --]

Index: gcc/fortran/class.c
===================================================================
--- gcc/fortran/class.c	(revision 201283)
+++ gcc/fortran/class.c	(working copy)
@@ -412,12 +412,12 @@ gfc_is_class_container_ref (gfc_expr *e)
 }
 
 
-/* Build a NULL initializer for CLASS pointers,
-   initializing the _data component to NULL and
-   the _vptr component to the declared type.  */
+/* Build an initializer for CLASS pointers,
+   initializing the _data component to the init_expr (or NULL) and the _vptr
+   component to the corresponding type (or the declared type, given by ts).  */
 
 gfc_expr *
-gfc_class_null_initializer (gfc_typespec *ts, gfc_expr *init_expr)
+gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
 {
   gfc_expr *init;
   gfc_component *comp;
@@ -430,6 +430,8 @@ gfc_expr *
 
   if (is_unlimited_polymorphic && init_expr)
     vtab = gfc_find_intrinsic_vtab (&ts->u.derived->components->ts);
+  else if (init_expr && init_expr->expr_type != EXPR_NULL)
+    vtab = gfc_find_derived_vtab (init_expr->ts.u.derived);
   else
     vtab = gfc_find_derived_vtab (ts->u.derived);
 
@@ -442,6 +444,8 @@ gfc_expr *
       gfc_constructor *ctor = gfc_constructor_get();
       if (strcmp (comp->name, "_vptr") == 0 && vtab)
 	ctor->expr = gfc_lval_expr_from_sym (vtab);
+      else if (init_expr && init_expr->expr_type != EXPR_NULL)
+	  ctor->expr = gfc_copy_expr (init_expr);
       else
 	ctor->expr = gfc_get_null_expr (NULL);
       gfc_constructor_append (&init->value.constructor, ctor);
Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h	(revision 201283)
+++ gcc/fortran/gfortran.h	(working copy)
@@ -2983,7 +2983,7 @@ void gfc_add_class_array_ref (gfc_expr *);
 bool gfc_is_class_array_ref (gfc_expr *, bool *);
 bool gfc_is_class_scalar_expr (gfc_expr *);
 bool gfc_is_class_container_ref (gfc_expr *e);
-gfc_expr *gfc_class_null_initializer (gfc_typespec *, gfc_expr *);
+gfc_expr *gfc_class_initializer (gfc_typespec *, gfc_expr *);
 unsigned int gfc_hash_value (gfc_symbol *);
 bool gfc_build_class_symbol (gfc_typespec *, symbol_attribute *,
 				gfc_array_spec **, bool);
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c	(revision 201283)
+++ gcc/fortran/trans-decl.c	(working copy)
@@ -1491,14 +1491,16 @@ gfc_get_symbol_decl (gfc_symbol * sym)
 	 SAVE is specified otherwise they need to be reinitialized
 	 every time the procedure is entered. The TREE_STATIC is
 	 in this case due to -fmax-stack-var-size=.  */
+      bool ptr = sym->attr.pointer || sym->attr.allocatable
+		 || (sym->ts.type == BT_CLASS
+		     && CLASS_DATA (sym)->attr.class_pointer);
+						  
       DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
 						  TREE_TYPE (decl),
 						  sym->attr.dimension
 						  || (sym->attr.codimension
 						      && sym->attr.allocatable),
-						  sym->attr.pointer
-						  || sym->attr.allocatable,
-						  sym->attr.proc_pointer);
+						  ptr, sym->attr.proc_pointer);
     }
 
   if (!TREE_STATIC (decl)
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 201283)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -5663,7 +5663,15 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespe
     }
   else if (pointer || procptr)
     {
-      if (!expr || expr->expr_type == EXPR_NULL)
+      if (ts->type == BT_CLASS && !procptr)
+	{
+	  gfc_init_se (&se, NULL);
+	  gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
+	  gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
+	  TREE_STATIC (se.expr) = 1;
+	  return se.expr;
+	}
+      else if (!expr || expr->expr_type == EXPR_NULL)
 	return fold_convert (type, null_pointer_node);
       else
 	{
@@ -5682,7 +5690,7 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespe
 	case BT_CLASS:
 	  gfc_init_se (&se, NULL);
 	  if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
-	    gfc_conv_structure (&se, gfc_class_null_initializer(ts, expr), 1);
+	    gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
 	  else
 	    gfc_conv_structure (&se, expr, 1);
 	  gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
@@ -5992,7 +6000,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_comp
     {
       /* NULL initialization for CLASS components.  */
       tmp = gfc_trans_structure_assign (dest,
-					gfc_class_null_initializer (&cm->ts, expr));
+					gfc_class_initializer (&cm->ts, expr));
       gfc_add_expr_to_block (&block, tmp);
     }
   else if (cm->attr.dimension && !cm->attr.proc_pointer)

[-- Attachment #3: pointer_init_8.f90 --]
[-- Type: application/octet-stream, Size: 573 bytes --]

! { dg-do compile }
!
! PR 57306: [OOP] ICE on valid with class pointer initialization
!
! Contributed by Andrew Benson <abensonca@gmail.com>

module m
  type :: c
  end type c
  type, extends(c) :: d
  end type d
  type(c), target :: x
  type(d), target :: y
end module m

 use m
  class(c), pointer :: px => x
  class(c), pointer :: py => y

  if (.not. associated(px, x))   call abort()
  if (.not. same_type_as(px, x)) call abort()
  if (.not. associated(py, y))   call abort()
  if (.not. same_type_as(py, y)) call abort()
end 

! { dg-final { cleanup-modules "m" } }

  reply	other threads:[~2013-07-30  7:15 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-26 21:13 Janus Weil
2013-07-27  9:51 ` Tobias Burnus
2013-07-29 21:20   ` Janus Weil
2013-07-29 23:04     ` Janus Weil
2013-07-29 23:53       ` Janus Weil
2013-07-30  9:11         ` Janus Weil [this message]
2013-08-02  9:01           ` Janus Weil
2013-08-04 21:13             ` Tobias Burnus
2013-08-04 22:13               ` Janus Weil
2013-08-05  9:16                 ` Janus Weil
2013-08-05 22:12           ` Tobias Burnus
2013-08-06  7:40             ` Janus Weil
2013-08-06  8:22               ` Janus Weil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAKwh3qh9KiNY6BF99m_cy=x=MQZrN_X0p+1idJ=rKSfB=1rhaw@mail.gmail.com' \
    --to=janus@gcc.gnu.org \
    --cc=burnus@net-b.de \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).