[flang] Fix LBOUND & UBOUND(function()), add tests

Original-commit: flang-compiler/f18@1e093e9927
Reviewed-on: https://github.com/flang-compiler/f18/pull/611
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2019-08-01 12:32:17 -07:00
parent 63423667fe
commit 6df445d0e7
3 changed files with 77 additions and 45 deletions

View File

@ -85,11 +85,11 @@ std::optional<DynamicType> ExpressionBase<A>::GetType() const {
return Result::GetType();
} else {
return std::visit(
[&](const auto &x) {
[&](const auto &x) -> std::optional<DynamicType> {
if constexpr (!common::HasMember<decltype(x), TypelessExpression>) {
return x.GetType();
} else {
return std::optional<DynamicType>{};
return std::nullopt;
}
},
derived().u);

View File

@ -357,7 +357,31 @@ Shape GetUpperBounds(FoldingContext &context, const NamedEntity &base) {
}
void GetShapeVisitor::Handle(const Symbol &symbol) {
std::visit(
common::visitors{
[&](const semantics::ObjectEntityDetails &object) {
Handle(NamedEntity{symbol});
},
[&](const semantics::AssocEntityDetails &assoc) {
Nested(assoc.expr());
},
[&](const semantics::SubprogramDetails &subp) {
if (subp.isFunction()) {
Handle(subp.result());
} else {
Return();
}
},
[&](const semantics::ProcBindingDetails &binding) {
Handle(binding.symbol());
},
[&](const semantics::UseDetails &use) { Handle(use.symbol()); },
[&](const semantics::HostAssocDetails &assoc) {
Handle(assoc.symbol());
},
[&](const auto &) { Return(); },
},
symbol.details());
}
void GetShapeVisitor::Handle(const Component &component) {
@ -369,23 +393,21 @@ void GetShapeVisitor::Handle(const Component &component) {
}
void GetShapeVisitor::Handle(const NamedEntity &base) {
const Symbol &symbol{ResolveAssociations(base.GetLastSymbol())};
if (const auto *details{symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
const Symbol &symbol{base.GetLastSymbol()};
if (const auto *object{symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
if (IsImpliedShape(symbol)) {
Nested(details->init());
Nested(object->init());
} else {
Shape result;
int n{static_cast<int>(details->shape().size())};
int n{static_cast<int>(object->shape().size())};
for (int dimension{0}; dimension < n; ++dimension) {
result.emplace_back(GetExtent(context_, base, dimension));
}
Return(std::move(result));
}
} else if (const auto *details{
symbol.detailsIf<semantics::AssocEntityDetails>()}) {
Nested(details->expr());
} else {
Return(); // error recovery
}
Return();
}
void GetShapeVisitor::Handle(const Substring &substring) {

View File

@ -15,7 +15,12 @@
! Test folding of LBOUND and UBOUND
subroutine test(n1,a1,a2)
module m
contains
function foo()
real :: foo(2:3,4:6)
end function
subroutine test(n1,a1,a2)
integer, intent(in) :: n1
real, intent(in) :: a1(0:n1), a2(0:*)
type :: t
@ -49,4 +54,9 @@ subroutine test(n1,a1,a2)
logical, parameter :: test_lbca2 = all(lbca2 == [1])
integer, parameter :: ubca2(:) = ubound(ca(:)(1:1))
logical, parameter :: test_ubca2 = all(ubca2 == [3])
integer, parameter :: lbfoo(:) = lbound(foo())
logical, parameter :: test_lbfoo = all(lbfoo == [1,1])
integer, parameter :: ubfoo(:) = ubound(foo())
logical, parameter :: test_ubfoo = all(ubfoo == [2,3])
end subroutine
end