aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorMatthew Gretton-Dann <matthew.gretton-dann@linaro.org>2013-05-14 09:55:27 +0000
committerMatthew Gretton-Dann <matthew.gretton-dann@linaro.org>2013-05-14 09:55:27 +0000
commitb5ae17f88f50279e4573f2959d42922c0c30b1db (patch)
tree5569c9b0222f5ff5603ae258582f94936128c806 /gcc/fortran
parent9c29cfa31a86897535882b5042585a7eb4bf3e2b (diff)
parentf9bf04177d912f484abfb9c3985d5e3b5c8e0bf0 (diff)
Merge from branches/gcc-4_8-branch r198615.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_8-branch@198871 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog53
-rw-r--r--gcc/fortran/check.c12
-rw-r--r--gcc/fortran/expr.c6
-rw-r--r--gcc/fortran/frontend-passes.c55
-rw-r--r--gcc/fortran/interface.c11
-rw-r--r--gcc/fortran/intrinsic.texi2
-rw-r--r--gcc/fortran/match.c11
-rw-r--r--gcc/fortran/parse.c6
-rw-r--r--gcc/fortran/target-memory.c46
-rw-r--r--gcc/fortran/target-memory.h2
10 files changed, 145 insertions, 59 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index cbed9baaceb..5c4128e0ee1 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,56 @@
+2013-04-26 Janus Weil <janus@gcc.gnu.org>
+
+ Backports from trunk:
+
+ PR fortran/56814
+ * interface.c (check_result_characteristics): Get result from interface
+ if present.
+
+ PR fortran/56968
+ * expr.c (gfc_check_pointer_assign): Handle generic functions returning
+ procedure pointers.
+
+ PR fortran/53685
+ PR fortran/57022
+ * check.c (gfc_calculate_transfer_sizes): Fix for array-valued SOURCE
+ expressions.
+ * target-memory.h (gfc_element_size): New prototype.
+ * target-memory.c (size_array): Remove.
+ (gfc_element_size): New function.
+ (gfc_target_expr_size): Modified to always return the full size of the
+ expression.
+
+2013-04-22 Thomas Koenig <tkoenig@gcc.gnu.org>
+ Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/56872
+ * frontend-passes.c (copy_walk_reduction_arg): Change argument type
+ to gfc_constructor. If it has an iterator, wrap the copy of its
+ expression in an array constructor with that iterator. Don't special
+ case function expressions.
+ (callback_reduction): Update caller. Don't return early if there is
+ an iterator.
+
+2013-04-18 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/56816
+ * match.c (gfc_match_select_type): Add syntax error. Move namespace
+ allocation and cleanup...
+ * parse.c (decode_statement): ... here.
+
+2013-04-18 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/56994
+ * invoke.texi (NEAREST): S argument is not optional.
+
+2013-04-08 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/56782
+ Backport fron trunk.
+ * frontend-passes.c (callback_reduction): Dont't do
+ any simplification if there is only a single element
+ which has an iterator.
+
2013-03-22 Release Manager
* GCC 4.8.0 released.
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 0e71b9506f8..586adee8b34 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -4017,8 +4017,6 @@ gfc_calculate_transfer_sizes (gfc_expr *source, gfc_expr *mold, gfc_expr *size,
size_t *result_length_p)
{
size_t result_elt_size;
- mpz_t tmp;
- gfc_expr *mold_element;
if (source->expr_type == EXPR_FUNCTION)
return FAILURE;
@@ -4027,20 +4025,12 @@ gfc_calculate_transfer_sizes (gfc_expr *source, gfc_expr *mold, gfc_expr *size,
return FAILURE;
/* Calculate the size of the source. */
- if (source->expr_type == EXPR_ARRAY
- && gfc_array_size (source, &tmp) == FAILURE)
- return FAILURE;
-
*source_size = gfc_target_expr_size (source);
if (*source_size == 0)
return FAILURE;
- mold_element = mold->expr_type == EXPR_ARRAY
- ? gfc_constructor_first (mold->value.constructor)->expr
- : mold;
-
/* Determine the size of the element. */
- result_elt_size = gfc_target_expr_size (mold_element);
+ result_elt_size = gfc_element_size (mold);
if (result_elt_size == 0)
return FAILURE;
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 1b74a44ab74..d16bdb09089 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -3528,7 +3528,11 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
}
else if (rvalue->expr_type == EXPR_FUNCTION)
{
- s2 = rvalue->symtree->n.sym->result;
+ if (rvalue->value.function.esym)
+ s2 = rvalue->value.function.esym->result;
+ else
+ s2 = rvalue->symtree->n.sym->result;
+
name = s2->name;
}
else
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index ead32f87882..fdfbce09465 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -188,37 +188,49 @@ optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
old one can be freed. */
static gfc_expr *
-copy_walk_reduction_arg (gfc_expr *e, gfc_expr *fn)
+copy_walk_reduction_arg (gfc_constructor *c, gfc_expr *fn)
{
- gfc_expr *fcn;
- gfc_isym_id id;
+ gfc_expr *fcn, *e = c->expr;
- if (e->rank == 0 || e->expr_type == EXPR_FUNCTION)
- fcn = gfc_copy_expr (e);
- else
+ fcn = gfc_copy_expr (e);
+ if (c->iterator)
{
- id = fn->value.function.isym->id;
+ gfc_constructor_base newbase;
+ gfc_expr *new_expr;
+ gfc_constructor *new_c;
+
+ newbase = NULL;
+ new_expr = gfc_get_expr ();
+ new_expr->expr_type = EXPR_ARRAY;
+ new_expr->ts = e->ts;
+ new_expr->where = e->where;
+ new_expr->rank = 1;
+ new_c = gfc_constructor_append_expr (&newbase, fcn, &(e->where));
+ new_c->iterator = c->iterator;
+ new_expr->value.constructor = newbase;
+ c->iterator = NULL;
+
+ fcn = new_expr;
+ }
+
+ if (fcn->rank != 0)
+ {
+ gfc_isym_id id = fn->value.function.isym->id;
if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
- fcn = gfc_build_intrinsic_call (current_ns,
- fn->value.function.isym->id,
+ fcn = gfc_build_intrinsic_call (current_ns, id,
fn->value.function.isym->name,
- fn->where, 3, gfc_copy_expr (e),
- NULL, NULL);
+ fn->where, 3, fcn, NULL, NULL);
else if (id == GFC_ISYM_ANY || id == GFC_ISYM_ALL)
- fcn = gfc_build_intrinsic_call (current_ns,
- fn->value.function.isym->id,
+ fcn = gfc_build_intrinsic_call (current_ns, id,
fn->value.function.isym->name,
- fn->where, 2, gfc_copy_expr (e),
- NULL);
+ fn->where, 2, fcn, NULL);
else
gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
}
- (void) gfc_expr_walker (&fcn, callback_reduction, NULL);
-
return fcn;
}
@@ -296,10 +308,15 @@ callback_reduction (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
c = gfc_constructor_first (arg->value.constructor);
+ /* Don't do any simplififcation if we have
+ - no element in the constructor or
+ - only have a single element in the array which contains an
+ iterator. */
+
if (c == NULL)
return 0;
- res = copy_walk_reduction_arg (c->expr, fn);
+ res = copy_walk_reduction_arg (c, fn);
c = gfc_constructor_next (c);
while (c)
@@ -311,7 +328,7 @@ callback_reduction (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
new_expr->where = fn->where;
new_expr->value.op.op = op;
new_expr->value.op.op1 = res;
- new_expr->value.op.op2 = copy_walk_reduction_arg (c->expr, fn);
+ new_expr->value.op.op2 = copy_walk_reduction_arg (c, fn);
res = new_expr;
c = gfc_constructor_next (c);
}
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index fff8c39ad93..5ea62757f22 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -1182,8 +1182,15 @@ check_result_characteristics (gfc_symbol *s1, gfc_symbol *s2,
{
gfc_symbol *r1, *r2;
- r1 = s1->result ? s1->result : s1;
- r2 = s2->result ? s2->result : s2;
+ if (s1->ts.interface && s1->ts.interface->result)
+ r1 = s1->ts.interface->result;
+ else
+ r1 = s1->result ? s1->result : s1;
+
+ if (s2->ts.interface && s2->ts.interface->result)
+ r2 = s2->ts.interface->result;
+ else
+ r2 = s2->result ? s2->result : s2;
if (r1->ts.type == BT_UNKNOWN)
return SUCCESS;
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index 4a48425cd83..1d8e0c0e7ec 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -9248,7 +9248,7 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{X} @tab Shall be of type @code{REAL}.
-@item @var{S} @tab (Optional) shall be of type @code{REAL} and
+@item @var{S} @tab Shall be of type @code{REAL} and
not equal to zero.
@end multitable
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index d75cf1cc17d..e9a701bb608 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -5364,7 +5364,6 @@ gfc_match_select_type (void)
char name[GFC_MAX_SYMBOL_LEN];
bool class_array;
gfc_symbol *sym;
- gfc_namespace *parent_ns;
m = gfc_match_label ();
if (m == MATCH_ERROR)
@@ -5374,8 +5373,6 @@ gfc_match_select_type (void)
if (m != MATCH_YES)
return m;
- gfc_current_ns = gfc_build_block_ns (gfc_current_ns);
-
m = gfc_match (" %n => %e", name, &expr2);
if (m == MATCH_YES)
{
@@ -5406,7 +5403,10 @@ gfc_match_select_type (void)
m = gfc_match (" )%t");
if (m != MATCH_YES)
- goto cleanup;
+ {
+ gfc_error ("parse error in SELECT TYPE statement at %C");
+ goto cleanup;
+ }
/* This ghastly expression seems to be needed to distinguish a CLASS
array, which can have a reference, from other expressions that
@@ -5444,9 +5444,6 @@ gfc_match_select_type (void)
return MATCH_YES;
cleanup:
- parent_ns = gfc_current_ns->parent;
- gfc_free_namespace (gfc_current_ns);
- gfc_current_ns = parent_ns;
return m;
}
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 6ee7b7fb85c..33d325d8df9 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -262,6 +262,7 @@ end_of_block:
static gfc_statement
decode_statement (void)
{
+ gfc_namespace *ns;
gfc_statement st;
locus old_locus;
match m;
@@ -363,7 +364,12 @@ decode_statement (void)
match (NULL, gfc_match_associate, ST_ASSOCIATE);
match (NULL, gfc_match_critical, ST_CRITICAL);
match (NULL, gfc_match_select, ST_SELECT_CASE);
+
+ gfc_current_ns = gfc_build_block_ns (gfc_current_ns);
match (NULL, gfc_match_select_type, ST_SELECT_TYPE);
+ ns = gfc_current_ns;
+ gfc_current_ns = gfc_current_ns->parent;
+ gfc_free_namespace (ns);
/* General statement matching: Instead of testing every possible
statement, we eliminate most possibilities by peeking at the
diff --git a/gcc/fortran/target-memory.c b/gcc/fortran/target-memory.c
index caad1b4368d..26a5de2326d 100644
--- a/gcc/fortran/target-memory.c
+++ b/gcc/fortran/target-memory.c
@@ -35,16 +35,6 @@ along with GCC; see the file COPYING3. If not see
/* --------------------------------------------------------------- */
/* Calculate the size of an expression. */
-static size_t
-size_array (gfc_expr *e)
-{
- mpz_t array_size;
- gfc_constructor *c = gfc_constructor_first (e->value.constructor);
- size_t elt_size = gfc_target_expr_size (c->expr);
-
- gfc_array_size (e, &array_size);
- return (size_t)mpz_get_ui (array_size) * elt_size;
-}
static size_t
size_integer (int kind)
@@ -82,16 +72,14 @@ size_character (int length, int kind)
}
+/* Return the size of a single element of the given expression.
+ Identical to gfc_target_expr_size for scalars. */
+
size_t
-gfc_target_expr_size (gfc_expr *e)
+gfc_element_size (gfc_expr *e)
{
tree type;
- gcc_assert (e != NULL);
-
- if (e->expr_type == EXPR_ARRAY)
- return size_array (e);
-
switch (e->ts.type)
{
case BT_INTEGER:
@@ -133,12 +121,36 @@ gfc_target_expr_size (gfc_expr *e)
return size;
}
default:
- gfc_internal_error ("Invalid expression in gfc_target_expr_size.");
+ gfc_internal_error ("Invalid expression in gfc_element_size.");
return 0;
}
}
+/* Return the size of an expression in its target representation. */
+
+size_t
+gfc_target_expr_size (gfc_expr *e)
+{
+ mpz_t tmp;
+ size_t asz;
+
+ gcc_assert (e != NULL);
+
+ if (e->rank)
+ {
+ if (gfc_array_size (e, &tmp))
+ asz = mpz_get_ui (tmp);
+ else
+ asz = 0;
+ }
+ else
+ asz = 1;
+
+ return asz * gfc_element_size (e);
+}
+
+
/* The encode_* functions export a value into a buffer, and
return the number of bytes of the buffer that have been
used. */
diff --git a/gcc/fortran/target-memory.h b/gcc/fortran/target-memory.h
index 8eebf8752cc..100321a2b7a 100644
--- a/gcc/fortran/target-memory.h
+++ b/gcc/fortran/target-memory.h
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see
/* Convert a BOZ to REAL or COMPLEX. */
bool gfc_convert_boz (gfc_expr *, gfc_typespec *);
-/* Return the size of an expression in its target representation. */
+size_t gfc_element_size (gfc_expr *);
size_t gfc_target_expr_size (gfc_expr *);
/* Write a constant expression in binary form to a target buffer. */