aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/expr.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2017-11-18 15:53:21 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2017-11-18 15:53:21 +0000
commita814e35ba380d278f95e703efb0cb672987983f7 (patch)
tree0173a2a632321dfc1979d34f3b3dc35818619d1b /gcc/fortran/expr.c
parentcde30fe04594843d87226653c19dbc5e05fad7b4 (diff)
downloadgcc-a814e35ba380d278f95e703efb0cb672987983f7.zip
gcc-a814e35ba380d278f95e703efb0cb672987983f7.tar.gz
gcc-a814e35ba380d278f95e703efb0cb672987983f7.tar.bz2
re PR fortran/83012 (Simply contiguous pointer function not recognized as contiguous)
2017-11-18 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/83012 * expr.c (gfc_is_simply_contiguous): If a function call through a class variable is done through a reference, check the function's interface. 2017-11-18 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/83012 * gfortran.dg/contiguous_5.f90: New test. From-SVN: r254914
Diffstat (limited to 'gcc/fortran/expr.c')
-rw-r--r--gcc/fortran/expr.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 09abacf..e1c0cac 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -5207,8 +5207,31 @@ gfc_is_simply_contiguous (gfc_expr *expr, bool strict, bool permit_element)
gfc_symbol *sym;
if (expr->expr_type == EXPR_FUNCTION)
- return expr->value.function.esym
- ? expr->value.function.esym->result->attr.contiguous : false;
+ {
+ if (expr->value.function.esym)
+ return expr->value.function.esym->result->attr.contiguous;
+ else
+ {
+ /* We have to jump through some hoops if this is a vtab entry. */
+ gfc_symbol *s;
+ gfc_ref *r, *rc;
+
+ s = expr->symtree->n.sym;
+ if (s->ts.type != BT_CLASS)
+ return false;
+
+ rc = NULL;
+ for (r = expr->ref; r; r = r->next)
+ if (r->type == REF_COMPONENT)
+ rc = r;
+
+ if (rc == NULL || rc->u.c.component == NULL
+ || rc->u.c.component->ts.interface == NULL)
+ return false;
+
+ return rc->u.c.component->ts.interface->attr.contiguous;
+ }
+ }
else if (expr->expr_type != EXPR_VARIABLE)
return false;