[flang-commits] [flang] [flang] Fix crash on self-referencing character length in function prefix (PR #194678)
via flang-commits
flang-commits at lists.llvm.org
Tue Apr 28 10:03:39 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Caroline Newcombe (cenewcombe)
<details>
<summary>Changes</summary>
**Bug Description:** `character*(a) function a()` causes a stack overflow in semantics. The function name in the character-length expression triggers `ConvertToObjectEntity`, which re-enters `CompleteFunctionResultType` before `ProcessTypeSpec` returns. Since `parsedType` is only cleared after `ProcessTypeSpec` returned, the re-entrant call walks the type-spec again, recursing infinitely.
**Fix:** clear `parsedType` before calling `ProcessTypeSpec` so re-entrant calls are no-ops.
**Testing:** A new semantics LIT test has been added with three cases. The first test case (`character(f1) function f1()`) is the bug reproducer — a simple name reference to the function in its own character-length expression, which caused infinite recursion. The second test case (`character(f2(1)) function f2()`) uses the function-call form of the self-reference, which already produced correct diagnostics before the fix. The third test case (`integer(f3) function f3()`) uses a self-referencing kind parameter, which was also found to crash without the fix.
---
Full diff: https://github.com/llvm/llvm-project/pull/194678.diff
2 Files Affected:
- (modified) flang/lib/Semantics/resolve-names.cpp (+5-2)
- (added) flang/test/Semantics/resolve128.f90 (+20)
``````````diff
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 3d42208688497..f87cbb67a1d05 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2985,9 +2985,13 @@ void FuncResultStack::CompleteFunctionResultType() {
if (info && &info->scope == &scopeHandler_.currScope() &&
info->resultSymbol) {
if (info->parsedType) {
+ // Clear parsedType first to avoid re-entrance via ConvertToObjectEntity
+ // when the type-spec references the function result name.
+ const auto *savedParsedType{info->parsedType};
+ info->parsedType = nullptr;
scopeHandler_.messageHandler().set_currStmtSource(info->source);
if (const auto *type{
- scopeHandler_.ProcessTypeSpec(*info->parsedType, true)}) {
+ scopeHandler_.ProcessTypeSpec(*savedParsedType, true)}) {
Symbol &symbol{*info->resultSymbol};
if (!scopeHandler_.context().HasError(symbol)) {
if (symbol.GetType()) {
@@ -2999,7 +3003,6 @@ void FuncResultStack::CompleteFunctionResultType() {
}
}
}
- info->parsedType = nullptr;
}
if (TypesMismatchIfNonNull(
info->resultSymbol->GetType(), info->previousImplicitType)) {
diff --git a/flang/test/Semantics/resolve128.f90 b/flang/test/Semantics/resolve128.f90
new file mode 100644
index 0000000000000..5acdcac1d9f5d
--- /dev/null
+++ b/flang/test/Semantics/resolve128.f90
@@ -0,0 +1,20 @@
+! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
+! Test that a self-referencing character length specification in a function
+! prefix does not cause infinite recursion (crash) in the compiler.
+
+! CHECK: error: Function cannot have both an explicit type prefix and a RESULT suffix
+character(f1) function f1()
+ implicit integer(f)
+ f = 2
+end function
+
+! CHECK: error: Use of 'f2' as a procedure conflicts with its declaration
+character(f2(1)) function f2()
+ implicit integer(f)
+ f = 2
+end function
+
+! CHECK: error: Must be a constant value
+integer(f3) function f3()
+ f3 = 2
+end function
``````````
</details>
https://github.com/llvm/llvm-project/pull/194678
More information about the flang-commits
mailing list