Found when looking at Julian's 3/4 OpenACC patch, which has not yet been committed (and needs still to be revised a bit.)
The fix (a) avoids an ICE when Julian's patch has been applied. The patch (b) just makes one error message less confusing. The testcase shows that only %re/%im run reach the new code as %kind/%len are != EXPR_VARIABLE. (The error message is slightly misleading if the 'list item'/'var' is not a variable.) (a) We need to handle REF_INQUIRY gfc_is_simplify_contiguous. That function is used for 'is_contiguous(a(:)%re)', but it works without this patch and simplifies already to .false. And it is used in openmp.c, which can ICE without this patch. (b) Just makes the error message nicer - as only EXPR_VARIABLE reaches that code, only %re and %im are mentioned in the error message. (Actually, it is not completely clear whether %re/%im are invalid or not; I think they should be – but one can argue otherwise. For OpenMP I just saw that it is tacked internally in Issue 2661, for OpenACC it is tracked as Issue 346 – but neither has been discussed, yet.) OK for mainline? Tobias PS: '%re'/'%im' permit accessing the real/imaginary part of a complex variable as lvalue (in the C++ sense) and also permit "var(:)%re = 1.0", which real(z) or imag(z) does not permit. var%kind == kind(var), but derived types also permit parameterized derived types (PDT), which can use '%foo' for respective 'len' and 'kind' components. ----------------- Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank Thürauf
Fortran: %re/%im fixes for OpenMP/OpenACC + gfc_is_simplify_contiguous gcc/fortran/ChangeLog: * expr.c (gfc_is_simplify_contiguous): Handle REF_INQUIRY, i.e. %im and %re which are EXPR_VARIABLE. * openmp.c (resolve_omp_clauses): Diagnose %re/%im explicitly. gcc/testsuite/ChangeLog: * gfortran.dg/goacc-gomp/ref_inquiry.f90: New test. gcc/fortran/expr.c | 2 ++ gcc/fortran/openmp.c | 8 +++++ .../gfortran.dg/goacc-gomp/ref_inquiry.f90 | 42 ++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 4f456fc629a..92a6700568d 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -5854,6 +5854,8 @@ gfc_is_simply_contiguous (gfc_expr *expr, bool strict, bool permit_element) part_ref = ref; else if (ref->type == REF_SUBSTRING) return false; + else if (ref->type == REF_INQUIRY) + return false; else if (ref->u.ar.type != AR_ELEMENT) ar = &ref->u.ar; } diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 797f6c86b62..f0307c801a5 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -5219,6 +5219,14 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, && array_ref->next->type == REF_SUBSTRING))) gfc_error ("Unexpected substring reference in %s clause " "at %L", name, &n->where); + else if (array_ref && array_ref->type == REF_INQUIRY) + { + gcc_assert (array_ref->u.i == INQUIRY_RE + || array_ref->u.i == INQUIRY_IM); + gfc_error ("Unexpected complex-parts designator " + "reference in %s clause at %L", + name, &n->where); + } else if (!resolved || n->expr->expr_type != EXPR_VARIABLE || array_ref->next diff --git a/gcc/testsuite/gfortran.dg/goacc-gomp/ref_inquiry.f90 b/gcc/testsuite/gfortran.dg/goacc-gomp/ref_inquiry.f90 new file mode 100644 index 00000000000..f92a6632af9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc-gomp/ref_inquiry.f90 @@ -0,0 +1,42 @@ +implicit none +type t + integer :: i + character :: c + complex :: z +end type t + +integer :: i +character(kind=4, len=5) :: c +complex :: z, zz(5) +type(t) :: x + +print *, is_contiguous(zz(:)%re) + +! EXPR_VARIABLE / Cf. also OpenMP spec issue 2661 +!$omp target enter data map(to: z%re) ! { dg-error "Unexpected complex-parts designator" } +!$omp target enter data map(to: z%im) ! { dg-error "Unexpected complex-parts designator" } +!$omp target enter data map(to: x%z%re) ! { dg-error "Unexpected complex-parts designator" } +!$omp target enter data map(to: x%z%im) ! { dg-error "Unexpected complex-parts designator" } + +! Fails differently as it is not a variable (EXPR_VARIABLE) +!$omp target enter data map(to: i%kind, c%len) ! { dg-error "not a proper array section" } +!$omp target enter data map(to: x%i%kind, x%c%len) ! { dg-error "not a proper array section" } + +! Likewise for OpenACC +!$acc enter data copyin(i%kind, c%len) ! { dg-error "not a proper array section" } +!$acc enter data copyin(x%i%kind) ! { dg-error "not a proper array section" } +!$acc enter data copyin(x%c%len) ! { dg-error "not a proper array section" } +!$acc update self(i%kind, c%len) ! { dg-error "not a proper array section" } +!$acc update self(x%i%kind) ! { dg-error "not a proper array section" } +!$acc update self(x%c%len) ! { dg-error "not a proper array section" } + +! EXPR_VARIABLE / cf. OpenACC spec issue 346 +!$acc enter data copyin(z%re) ! { dg-error "Unexpected complex-parts designator" } +!$acc enter data copyin(z%im) ! { dg-error "Unexpected complex-parts designator" } +!$acc enter data copyin(x%z%re) ! { dg-error "Unexpected complex-parts designator" } +!$acc enter data copyin(x%z%im) ! { dg-error "Unexpected complex-parts designator" } +!$acc update self(z%re) ! { dg-error "Unexpected complex-parts designator" } +!$acc update self(z%im) ! { dg-error "Unexpected complex-parts designator" } +!$acc update self(zz%re) +!$acc update self(zz%im) +end