aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2020-09-30 15:01:13 +0200
committerTobias Burnus <tobias@codesourcery.com>2020-09-30 15:01:13 +0200
commit65167982efa4dbb96698d026e6d7e17acb513f0a (patch)
tree3d5bc9c39be8e950bd889436ee84d1148c0ae582 /gcc/fortran
parent8b0a63e47cd83f4e8534d0d201739bdd10f321a2 (diff)
downloadgcc-65167982efa4dbb96698d026e6d7e17acb513f0a.zip
gcc-65167982efa4dbb96698d026e6d7e17acb513f0a.tar.gz
gcc-65167982efa4dbb96698d026e6d7e17acb513f0a.tar.bz2
Fortran: add contiguous check for ptr assignment, fix non-contig check (PR97242)
gcc/fortran/ChangeLog: PR fortran/97242 * expr.c (gfc_is_not_contiguous): Fix check. (gfc_check_pointer_assign): Use it. gcc/testsuite/ChangeLog: PR fortran/97242 * gfortran.dg/contiguous_11.f90: New test. * gfortran.dg/contiguous_4.f90: Update. * gfortran.dg/contiguous_7.f90: Update.
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/expr.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 68784a2..b87ae3d 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -4366,10 +4366,18 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue,
contiguous. */
if (lhs_attr.contiguous
- && lhs_attr.dimension > 0
- && !gfc_is_simply_contiguous (rvalue, false, true))
- gfc_warning (OPT_Wextra, "Assignment to contiguous pointer from "
- "non-contiguous target at %L", &rvalue->where);
+ && lhs_attr.dimension > 0)
+ {
+ if (gfc_is_not_contiguous (rvalue))
+ {
+ gfc_error ("Assignment to contiguous pointer from "
+ "non-contiguous target at %L", &rvalue->where);
+ return false;
+ }
+ if (!gfc_is_simply_contiguous (rvalue, false, true))
+ gfc_warning (OPT_Wextra, "Assignment to contiguous pointer from "
+ "non-contiguous target at %L", &rvalue->where);
+ }
/* Warn if it is the LHS pointer may lives longer than the RHS target. */
if (warn_target_lifetime
@@ -5935,7 +5943,7 @@ gfc_is_not_contiguous (gfc_expr *array)
{
/* Array-ref shall be last ref. */
- if (ar)
+ if (ar && ar->type != AR_ELEMENT)
return true;
if (ref->type == REF_ARRAY)
@@ -5955,10 +5963,11 @@ gfc_is_not_contiguous (gfc_expr *array)
if (gfc_ref_dimen_size (ar, i, &ref_size, NULL))
{
- if (gfc_dep_difference (ar->as->lower[i], ar->as->upper[i], &arr_size))
+ if (gfc_dep_difference (ar->as->upper[i], ar->as->lower[i], &arr_size))
{
/* a(2:4,2:) is known to be non-contiguous, but
a(2:4,i:i) can be contiguous. */
+ mpz_add_ui (arr_size, arr_size, 1L);
if (previous_incomplete && mpz_cmp_si (ref_size, 1) != 0)
{
mpz_clear (arr_size);
@@ -5979,7 +5988,10 @@ gfc_is_not_contiguous (gfc_expr *array)
&& ar->dimen_type[i] == DIMEN_RANGE
&& ar->stride[i] && ar->stride[i]->expr_type == EXPR_CONSTANT
&& mpz_cmp_si (ar->stride[i]->value.integer, 1) != 0)
- return true;
+ {
+ mpz_clear (ref_size);
+ return true;
+ }
mpz_clear (ref_size);
}