[flang-commits] [PATCH] D153569: [flang] Avoid crash in statement function error case
Peter Klausler via Phabricator via flang-commits
flang-commits at lists.llvm.org
Thu Jun 22 09:27:19 PDT 2023
klausler created this revision.
klausler added a reviewer: PeteSteinfeld.
klausler added a project: Flang.
Herald added subscribers: sunshaoce, jdoerfert.
Herald added a project: All.
klausler requested review of this revision.
The predicate IsPureProcedure() crashes with infinite
recursion when presented with mutually recursive statement
functions -- an error case that should be recoverable.
Fix by adding a visited set.
Fixes bug https://github.com/llvm/llvm-project/issues/63231
https://reviews.llvm.org/D153569
Files:
flang/lib/Evaluate/tools.cpp
flang/test/Semantics/stmt-func01.f90
Index: flang/test/Semantics/stmt-func01.f90
===================================================================
--- flang/test/Semantics/stmt-func01.f90
+++ flang/test/Semantics/stmt-func01.f90
@@ -34,7 +34,10 @@
integer :: sf9
!ERROR: Defining expression of statement function 'sf9' cannot be converted to its result type INTEGER(4)
sf9(n) = "bad"
- sf10 = 1.
+ !ERROR: Statement function 'sf10' may not reference another statement function 'sf11' that is defined later
+ sf10(n) = sf11(n)
+ sf11(n) = sf10(n) ! mutual recursion, caused crash
+ sf13 = 1.
contains
real function explicit(x,y)
integer, intent(in) :: x
@@ -47,6 +50,6 @@
end function
subroutine foo
!PORTABILITY: An implicitly typed statement function should not appear when the same symbol is available in its host scope
- sf10(x) = 2.*x
+ sf13(x) = 2.*x
end subroutine
end
Index: flang/lib/Evaluate/tools.cpp
===================================================================
--- flang/lib/Evaluate/tools.cpp
+++ flang/lib/Evaluate/tools.cpp
@@ -1272,16 +1272,21 @@
ultimate.has<AssocEntityDetails>());
}
-bool IsPureProcedure(const Symbol &original) {
+static bool IsPureProcedureImpl(
+ const Symbol &original, semantics::UnorderedSymbolSet &set) {
// An ENTRY is pure if its containing subprogram is
const Symbol &symbol{DEREF(GetMainEntry(&original.GetUltimate()))};
+ if (set.find(symbol) != set.end()) {
+ return true;
+ }
+ set.emplace(symbol);
if (const auto *procDetails{symbol.detailsIf<ProcEntityDetails>()}) {
if (procDetails->procInterface()) {
// procedure with a pure interface
- return IsPureProcedure(*procDetails->procInterface());
+ return IsPureProcedureImpl(*procDetails->procInterface(), set);
}
} else if (const auto *details{symbol.detailsIf<ProcBindingDetails>()}) {
- return IsPureProcedure(details->symbol());
+ return IsPureProcedureImpl(details->symbol(), set);
} else if (!IsProcedure(symbol)) {
return false;
}
@@ -1293,7 +1298,7 @@
if (&*ref == &symbol) {
return false; // error recovery, recursion is caught elsewhere
}
- if (IsFunction(*ref) && !IsPureProcedure(*ref)) {
+ if (IsFunction(*ref) && !IsPureProcedureImpl(*ref, set)) {
return false;
}
if (ref->GetUltimate().attrs().test(Attr::VOLATILE)) {
@@ -1308,6 +1313,11 @@
!symbol.attrs().test(Attr::IMPURE));
}
+bool IsPureProcedure(const Symbol &original) {
+ semantics::UnorderedSymbolSet set;
+ return IsPureProcedureImpl(original, set);
+}
+
bool IsPureProcedure(const Scope &scope) {
const Symbol *symbol{scope.GetSymbol()};
return symbol && IsPureProcedure(*symbol);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153569.533652.patch
Type: text/x-patch
Size: 2748 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20230622/4767a3a5/attachment.bin>
More information about the flang-commits
mailing list