Skip to content

Commit 8ac9eac

Browse files
klauslerjeanPerier
authored andcommitted
[flang] Enforce array conformance in actual arguments to ELEMENTALs
When the shapes of actual arguments to ELEMENTAL procedures are sufficiently well known during semantics, require them to conform. Differential Revision: https://reviews.llvm.org/D109909
1 parent b707e7f commit 8ac9eac

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

flang/lib/Semantics/check-call.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,41 @@ static void RearrangeArguments(const characteristics::Procedure &proc,
722722
}
723723
}
724724

725+
// The actual argument arrays to an ELEMENTAL procedure must conform.
726+
static bool CheckElementalConformance(parser::ContextualMessages &messages,
727+
const characteristics::Procedure &proc, evaluate::ActualArguments &actuals,
728+
evaluate::FoldingContext &context) {
729+
std::optional<evaluate::Shape> shape;
730+
std::string shapeName;
731+
int index{0};
732+
for (const auto &arg : actuals) {
733+
const auto &dummy{proc.dummyArguments.at(index++)};
734+
if (arg) {
735+
if (const auto *expr{arg->UnwrapExpr()}) {
736+
if (auto argShape{evaluate::GetShape(context, *expr)}) {
737+
if (GetRank(*argShape) > 0) {
738+
std::string argName{"actual argument ("s + expr->AsFortran() +
739+
") corresponding to dummy argument #" + std::to_string(index) +
740+
" ('" + dummy.name + "')"};
741+
if (shape) {
742+
auto tristate{evaluate::CheckConformance(messages, *shape,
743+
*argShape, evaluate::CheckConformanceFlags::None,
744+
shapeName.c_str(), argName.c_str())};
745+
if (tristate && !*tristate) {
746+
return false;
747+
}
748+
} else {
749+
shape = std::move(argShape);
750+
shapeName = argName;
751+
}
752+
}
753+
}
754+
}
755+
}
756+
}
757+
return true;
758+
}
759+
725760
static parser::Messages CheckExplicitInterface(
726761
const characteristics::Procedure &proc, evaluate::ActualArguments &actuals,
727762
const evaluate::FoldingContext &context, const Scope *scope,
@@ -751,6 +786,9 @@ static parser::Messages CheckExplicitInterface(
751786
}
752787
}
753788
}
789+
if (proc.IsElemental() && !buffer.AnyFatalError()) {
790+
CheckElementalConformance(messages, proc, actuals, localContext);
791+
}
754792
}
755793
return buffer;
756794
}

flang/test/Semantics/call22.f90

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
! RUN: %python %S/test_errors.py %s %flang_fc1
2+
! Enforce array conformance across actual arguments to ELEMENTAL
3+
module m
4+
contains
5+
real elemental function f(a, b)
6+
real, intent(in) :: a, b
7+
f = a + b
8+
end function
9+
real function g(n)
10+
integer, value :: n
11+
g = sqrt(real(n))
12+
end function
13+
subroutine test
14+
real :: a(3) = [1, 2, 3]
15+
!ERROR: Dimension 1 of actual argument (a) corresponding to dummy argument #1 ('a') has extent 3, but actual argument ([REAL(4)::(g(int(j,kind=4)),INTEGER(8)::j=1_8,2_8,1_8)]) corresponding to dummy argument #2 ('b') has extent 2
16+
print *, f(a, [(g(j), j=1, 2)])
17+
end subroutine
18+
end

0 commit comments

Comments
 (0)