aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2014-08-14 18:52:12 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2014-08-14 18:52:12 +0000
commitba8aa6fca60d3db6375b5f2c1ca6ab57d5ba97da (patch)
treec05298e642e4da5fff2ed70900313cdb25f9d8c4 /gcc
parentbc0229f9f6929e000bc638e26fcd25ff0e95b2ed (diff)
downloadgcc-ba8aa6fca60d3db6375b5f2c1ca6ab57d5ba97da.zip
gcc-ba8aa6fca60d3db6375b5f2c1ca6ab57d5ba97da.tar.gz
gcc-ba8aa6fca60d3db6375b5f2c1ca6ab57d5ba97da.tar.bz2
re PR fortran/62106 (Adding a scalar variable to an array constructor gives wrong result)
2014-08-14 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-14 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/62106 * gfortran.dg/array_constructor_49.f90: New test. From-SVN: r213980
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog10
-rw-r--r--gcc/fortran/frontend-passes.c26
-rw-r--r--gcc/fortran/gfortran.h2
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gfortran.dg/array_constructor_49.f9013
5 files changed, 51 insertions, 7 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 4a37198..a8930a9 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,13 @@
+2014-08-14 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-14 Tobias Burnus <burnus@net-b.de>
* gfortran.texi (caf_register_t): Add CAF_REGTYPE_CRITICAL.
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index 4646cc3..edf6348 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -430,11 +430,26 @@ cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
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;
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index f1750da..e84acea 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d56f36a..b879b3a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-08-14 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/62106
+ * gfortran.dg/array_constructor_49.f90: New test.
+
2014-08-14 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/54377
@@ -115,7 +120,7 @@
PR tree-optimization/62073
* gcc.dg/vect/pr62073.c: New test.
-
+
2014-08-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/62070
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_49.f90 b/gcc/testsuite/gfortran.dg/array_constructor_49.f90
new file mode 100644
index 0000000..6a198d6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_constructor_49.f90
@@ -0,0 +1,13 @@
+! { dg-do run }
+! { dg-options "-ffrontend-optimize -fdump-tree-original" }
+! PR 62106 - this used to give wrong results because
+! of a bogus extra temporary variable.
+! Original test case by Martien Hulsen
+program t
+ integer :: ndim=2, ndfp=4, i
+ character (len=8) :: line
+ write (unit=line,fmt='(4I2)'), (/ ( i, i = 1, ndfp ) /) + ndim
+ if (line /= ' 3 4 5 6') call abort
+end program t
+! { dg-final { scan-tree-dump-times "__var" 3 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }