diff mbox

[fortran] Fix PR 62106

Message ID 53ECF4A4.8020004@netcologne.de
State New
Headers show

Commit Message

Thomas Koenig Aug. 14, 2014, 5:40 p.m. UTC
Hello world,

the attached patch fixes the regression by making sure we never
try to create a temporary variable from a temporary variable,
which happened in the wrong order.

Regression-tested.  OK for trunk and 4.9?

2014-08-19  Thomas Koenig  <tkoenig@gcc.gnu.org>

        PR fortran/62106
        * gfortran.h (symbol_attribute):  Add fe_temp flag.
        * frontend-passes.c (is_fe_temp):  New function.
        (create_var):  Don't add a temporary for an already
        created variable or for a constant.
        (combine_ARRAY_constructor):  Remove special handling
        for constants.

2014-08-19  Thomas Koenig  <tkoenig@gcc.gnu.org>

        PR fortran/62106
        * gfortran.dg/array_constructor_49.f90:  New test.

Comments

Steve Kargl Aug. 14, 2014, 6:13 p.m. UTC | #1
On Thu, Aug 14, 2014 at 07:40:52PM +0200, Thomas Koenig wrote:
> Hello world,
> 
> the attached patch fixes the regression by making sure we never
> try to create a temporary variable from a temporary variable,
> which happened in the wrong order.
> 
> Regression-tested.  OK for trunk and 4.9?
> 

Looks good to me.
diff mbox

Patch

Index: frontend-passes.c
===================================================================
--- frontend-passes.c	(Revision 213778)
+++ frontend-passes.c	(Arbeitskopie)
@@ -430,11 +430,26 @@  cfe_register_funcs (gfc_expr **e, int *walk_subtre
   return 0;
 }
 
+/* Auxiliary function to check if an expression is a temporary created by
+   create var.  */
+
+static bool
+is_fe_temp (gfc_expr *e)
+{
+  if (e->expr_type != EXPR_VARIABLE)
+    return false;
+
+  return e->symtree->n.sym->attr.fe_temp;
+}
+
+
 /* Returns a new expression (a variable) to be used in place of the old one,
    with an assignment statement before the current statement to set
    the value of the variable. Creates a new BLOCK for the statement if
    that hasn't already been done and puts the statement, plus the
-   newly created variables, in that block.  */
+   newly created variables, in that block.  Special cases:  If the
+   expression is constant or a temporary which has already
+   been created, just copy it.  */
 
 static gfc_expr*
 create_var (gfc_expr * e)
@@ -448,6 +463,9 @@  create_var (gfc_expr * e)
   gfc_namespace *ns;
   int i;
 
+  if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e))
+    return gfc_copy_expr (e);
+
   /* If the block hasn't already been created, do so.  */
   if (inserted_block == NULL)
     {
@@ -522,6 +540,7 @@  create_var (gfc_expr * e)
   symbol->attr.flavor = FL_VARIABLE;
   symbol->attr.referenced = 1;
   symbol->attr.dimension = e->rank > 0;
+  symbol->attr.fe_temp = 1;
   gfc_commit_symbol (symbol);
 
   result = gfc_get_expr ();
@@ -1082,10 +1101,7 @@  combine_array_constructor (gfc_expr *e)
   if (op2->ts.type == BT_CHARACTER)
     return false;
 
-  if (op2->expr_type == EXPR_CONSTANT)
-    scalar = gfc_copy_expr (op2);
-  else
-    scalar = create_var (gfc_copy_expr (op2));
+  scalar = create_var (gfc_copy_expr (op2));
 
   oldbase = op1->value.constructor;
   newbase = NULL;
Index: gfortran.h
===================================================================
--- gfortran.h	(Revision 213778)
+++ gfortran.h	(Arbeitskopie)
@@ -739,7 +739,7 @@  typedef struct
     optional:1, pointer:1, target:1, value:1, volatile_:1, temporary:1,
     dummy:1, result:1, assign:1, threadprivate:1, not_always_present:1,
     implied_index:1, subref_array_pointer:1, proc_pointer:1, asynchronous:1,
-    contiguous:1;
+    contiguous:1, fe_temp: 1;
 
   /* For CLASS containers, the pointer attribute is sometimes set internally
      even though it was not directly specified.  In this case, keep the