diff mbox

[Fortran,OOP] PR 64209: runtime segfault with CLASS(*), INTENT(OUT) dummy argument

Message ID CAKwh3qg+uDkDzc+7=L7n6ESYdObe8kcErks7U4T_Kwe2HCXRvQ@mail.gmail.com
State New
Headers show

Commit Message

Janus Weil Dec. 19, 2014, 12:39 p.m. UTC
Hi all,

the attached patch fixes a wrong-code issue with unlimited poylmorphic
INTENT(OUT) arguments.

We default-initialize all polymorphic INTENT(OUT) arguments via the
_def_init component of the vtable. The problem is that the intrinsic
types don't have a default initialization. Therefore their _def_init
is NULL and we simply failed to check for that condition. That's what
the patch does. It regtests cleanly on x86_64-unknown-linux-gnu.

Ok for trunk?

Cheers,
Janus



2014-12-19  Janus Weil  <janus@gcc.gnu.org>

    PR fortran/64209
    * trans-expr.c (gfc_trans_class_array_init_assign): Check if _def_init
    component is non-NULL.
    (gfc_trans_class_init_assign): Ditto.

2014-12-19  Janus Weil  <janus@gcc.gnu.org>

    PR fortran/64209
    * gfortran.dg/unlimited_polymorphic_19.f90: New.

Comments

Tobias Burnus Dec. 19, 2014, 1:48 p.m. UTC | #1
Janus Weil wrote:
> the attached patch fixes a wrong-code issue with unlimited poylmorphic
> INTENT(OUT) arguments.
>
> We default-initialize all polymorphic INTENT(OUT) arguments via the
> _def_init component of the vtable. The problem is that the intrinsic
> types don't have a default initialization. Therefore their _def_init
> is NULL and we simply failed to check for that condition. That's what
> the patch does. It regtests cleanly on x86_64-unknown-linux-gnu.
> 
> Ok for trunk?

As you write yourself, the issue can only occur for CLASS(*). Hence,
please apply this only for UNLIMITED_POLY() to avoid unneccessary code side
increase and performance decrease.

OK this this change. Thanks for the patch!

Tobias
diff mbox

Patch

Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(Revision 218896)
+++ gcc/fortran/trans-expr.c	(Arbeitskopie)
@@ -912,7 +912,8 @@  gfc_trans_class_array_init_assign (gfc_expr *rhs,
   gfc_actual_arglist *actual;
   gfc_expr *ppc;
   gfc_code *ppc_code;
-  tree res;
+  tree res, cond;
+  gfc_se src;
 
   actual = gfc_get_actual_arglist ();
   actual->expr = gfc_copy_expr (rhs);
@@ -932,6 +933,16 @@  gfc_trans_class_array_init_assign (gfc_expr *rhs,
      of arrays in gfc_trans_call.  */
   res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
   gfc_free_statements (ppc_code);
+
+  gfc_init_se (&src, NULL);
+  gfc_conv_expr (&src, rhs);
+  src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
+  cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
+			  src.expr, fold_convert (TREE_TYPE (src.expr),
+						  null_pointer_node));
+  res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
+		    build_empty_stmt (input_location));
+
   return res;
 }
 
@@ -943,7 +954,7 @@  tree
 gfc_trans_class_init_assign (gfc_code *code)
 {
   stmtblock_t block;
-  tree tmp;
+  tree tmp, cond;
   gfc_se dst,src,memsz;
   gfc_expr *lhs, *rhs, *sz;
 
@@ -980,6 +991,12 @@  gfc_trans_class_init_assign (gfc_code *code)
       src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
 
       tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
+
+      cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
+			      src.expr, fold_convert (TREE_TYPE (src.expr),
+						      null_pointer_node));
+      tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond, tmp,
+			build_empty_stmt (input_location));
     }
 
   if (code->expr1->symtree->n.sym->attr.optional