diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2014-08-14 18:52:12 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2014-08-14 18:52:12 +0000 |
commit | ba8aa6fca60d3db6375b5f2c1ca6ab57d5ba97da (patch) | |
tree | c05298e642e4da5fff2ed70900313cdb25f9d8c4 /gcc | |
parent | bc0229f9f6929e000bc638e26fcd25ff0e95b2ed (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/fortran/frontend-passes.c | 26 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/array_constructor_49.f90 | 13 |
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" } } |