diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp --- a/flang/lib/Evaluate/check-expression.cpp +++ b/flang/lib/Evaluate/check-expression.cpp @@ -765,6 +765,8 @@ // simple contiguity to allow their use in contexts like // data targets in pointer assignments with remapping. return true; + } else if (ultimate.has()) { + return Base::operator()(ultimate); // use expr } else if (semantics::IsPointer(ultimate) || semantics::IsAssumedShape(ultimate)) { return std::nullopt; diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -6655,8 +6655,8 @@ // If current selector is a variable, set some of its attributes on symbol. void ConstructVisitor::SetAttrsFromAssociation(Symbol &symbol) { Attrs attrs{evaluate::GetAttrs(GetCurrentAssociation().selector.expr)}; - symbol.attrs() |= attrs & - Attrs{Attr::TARGET, Attr::ASYNCHRONOUS, Attr::VOLATILE, Attr::CONTIGUOUS}; + symbol.attrs() |= + attrs & Attrs{Attr::TARGET, Attr::ASYNCHRONOUS, Attr::VOLATILE}; if (attrs.test(Attr::POINTER)) { SetImplicitAttr(symbol, Attr::TARGET); } diff --git a/flang/test/Evaluate/folding09.f90 b/flang/test/Evaluate/folding09.f90 --- a/flang/test/Evaluate/folding09.f90 +++ b/flang/test/Evaluate/folding09.f90 @@ -1,6 +1,5 @@ ! RUN: %python %S/test_folding.py %s %flang_fc1 -! Test folding of IS_CONTIGUOUS on simply contiguous items (9.5.4) -! When IS_CONTIGUOUS() is constant, it's .TRUE. +! Test folding of IS_CONTIGUOUS module m real, target :: hosted(2) @@ -14,17 +13,39 @@ real, intent(in), contiguous :: arr3(:) real, allocatable :: alloc(:) real :: scalar - logical, parameter :: test_isc01 = is_contiguous(0) - logical, parameter :: test_isc02 = is_contiguous(scalar) - logical, parameter :: test_isc03 = is_contiguous(scalar + scalar) - logical, parameter :: test_isc04 = is_contiguous([0, 1, 2]) - logical, parameter :: test_isc05 = is_contiguous(arr1 + 1.0) - logical, parameter :: test_isc06 = is_contiguous(arr2) - logical, parameter :: test_isc07 = is_contiguous(mat) - logical, parameter :: test_isc08 = is_contiguous(mat(1:10,1)) - logical, parameter :: test_isc09 = is_contiguous(arr2(1:10:1)) - logical, parameter :: test_isc10 = is_contiguous(arr3) - logical, parameter :: test_isc11 = is_contiguous(f()) - logical, parameter :: test_isc12 = is_contiguous(alloc) + integer(kind=merge(1,-1, is_contiguous(0))) t01 + integer(kind=merge(1,-1, is_contiguous(scalar))) t02 + integer(kind=merge(1,-1, is_contiguous(scalar + scalar))) t03 + integer(kind=merge(1,-1, is_contiguous([0, 1, 2]))) t04 + integer(kind=merge(1,-1, is_contiguous(arr1 + 1.0))) t05 + integer(kind=merge(1,-1, is_contiguous(arr2))) t06 + integer(kind=merge(1,-1, is_contiguous(mat))) t07 + integer(kind=merge(1,-1, is_contiguous(mat(1:10,1)))) t08 + integer(kind=merge(1,-1, is_contiguous(arr2(1:10:1)))) t09 + integer(kind=merge(1,-1, .not. is_contiguous(arr2(1:10:2)))) t10 + integer(kind=merge(1,-1, is_contiguous(arr3))) t11 + integer(kind=merge(1,-1, .not. is_contiguous(arr3(1:10:2)))) t12 + integer(kind=merge(1,-1, is_contiguous(f()))) t13 + integer(kind=merge(1,-1, is_contiguous(alloc))) t14 + associate (x => arr2) + block + integer(kind=merge(1,-1,is_contiguous(x))) n + end block + end associate + associate (x => arr2(1:10:2)) + block + integer(kind=merge(1,-1,.not. is_contiguous(x))) n + end block + end associate + associate (x => arr3) + block + integer(kind=merge(1,-1,is_contiguous(x))) n + end block + end associate + associate (x => arr3(1:10:2)) + block + integer(kind=merge(1,-1,.not. is_contiguous(x))) n + end block + end associate end subroutine end module diff --git a/flang/test/Lower/HLFIR/associate-construct.f90 b/flang/test/Lower/HLFIR/associate-construct.f90 --- a/flang/test/Lower/HLFIR/associate-construct.f90 +++ b/flang/test/Lower/HLFIR/associate-construct.f90 @@ -32,7 +32,7 @@ subroutine associate_pointer(x) integer, pointer, contiguous :: x(:) - ! Check that "y" has the target and contiguous attributes. + ! Check that "y" has the target attribute. associate(y => x) print *, y end associate @@ -44,7 +44,7 @@ ! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index ! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) ! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1> -! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_6]]) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFassociate_pointerEy"} : (!fir.ptr>, !fir.shapeshift<1>) -> (!fir.box>, !fir.ptr>) +! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_6]]) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFassociate_pointerEy"} : (!fir.ptr>, !fir.shapeshift<1>) -> (!fir.box>, !fir.ptr>) ! CHECK: fir.call @_FortranAioEndIoStatement ! CHECK-NEXT: return @@ -92,6 +92,6 @@ ! CHECK: %[[VAL_6:.*]] = arith.constant 20 : index ! CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_2]]{{.*}} ! CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> -! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]](%[[VAL_9]]) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFassociate_pointer_sectionEy"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]](%[[VAL_9]]) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFassociate_pointer_sectionEy"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! CHECK: fir.call @_FortranAioEndIoStatement ! CHECK-NEXT: return