llvm / llvm/llvm-project

[flang] crashes with "fatal internal error: unexpected type" when a conditional argument appears in a reference that resolves to a structure constructor

Open
#223,426 1 comment 0 reactions 0 assignees View on GitHub
crash flang:frontend
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

When a generic interface shares its name with a derived type and a reference to
that name contains an F2023 conditional argument, and no specific procedure
matches (so generic resolution falls back to interpreting the reference as a
structure constructor), flang aborts with

```
fatal internal error: unexpected type
```

instead of emitting a diagnostic. The program is non-conforming — a
*conditional-arg* is an actual-argument form (F2023 R1524/R1526) and is not a
valid *component-data-source* (R757) — so an error message is expected, not a
crash.

Reproducer (`repro.f90`):

```fortran
module m
type :: g
integer :: c
end type
interface g
module procedure g_real
end interface
contains
type(g) function g_real(x)
real, intent(in) :: x
g_real%c = int(x)
end function
end module

subroutine test(flag)
use m
logical, intent(in) :: flag
integer :: ia
integer :: ib
type(g) :: v
ia = 1; ib = 2
v = g((flag ? ia : ib))
end subroutine
```

```
$ flang -fsyntax-only repro.f90

fatal internal error: unexpected type
```

The consequents here are deliberately attribute-consistent plain integers, so
the crash is independent of the C1545 consistency rules: it reproduces
identically whether the consequents mix ALLOCATABLE/POINTER/corank or not.
The only specific (`g_real`) takes a REAL, so the INTEGER-typed conditional
argument matches no specific and resolution falls through to the
structure-constructor interpretation of `g(...)`.

Where it dies: `ActualArgToExpr()` in `flang/lib/Parser/parse-tree.cpp`
(the helper used by `FunctionReference::ConvertToStructureConstructor`)
handles only the `common::Indirection` and `common::Indirection`
alternatives of `ActualArg` and ends in

```c++
[&](auto &) -> Expr { common::die("unexpected type"); },
```

so an `ActualArg` holding a `ConditionalArg` (or, presumably, an
`AltReturnSpec` or `PercentRef`/`PercentVal`) reaches the `die` as soon as the
reference is reinterpreted as a structure constructor. A clean fix would
diagnose "a conditional argument is not a valid component data source" (or
refuse the structure-constructor reinterpretation when any actual argument is
not an expression) before the conversion.

Backtrace excerpt (symbol names; frame addresses elided):

```
fatal internal error: unexpected type
...
#10 Fortran::parser::ArrayElement::ConvertToStructureConstructor(...) (.cold) parse-tree.cpp
[inlined ActualArgToExpr; called from FunctionReference::ConvertToStructureConstructor]
#11 Fortran::evaluate::ExpressionAnalyzer::Analyze(Fortran::parser::FunctionReference const&,
std::optional*)
#12 Fortran::evaluate::ExpressionAnalyzer::ExprOrVariable(...)
#13 Fortran::evaluate::ExpressionAnalyzer::IterativelyAnalyzeSubexpressions(...)
#14 Fortran::evaluate::ExpressionAnalyzer::Analyze(Fortran::parser::Expr const&)
#15 Fortran::evaluate::ArgumentAnalyzer::AnalyzeExprOrWholeAssumedSizeArray(...)
```

Verified with flang 24.0.0git at 980c9bbdd3ddda88da6b8b63261c8d514c5d4306 and
again at 2078cc8bfe5cdabc47a744810efc52bcca977cb7 (2026-09-11 main), x86_64
Linux, assertions enabled.

Related: found while testing #219581 (which scopes C1545 to generic
references, fixing #209840). That change is orthogonal: with it applied, a
*mixed-attribute* conditional argument in this shape gets the C1545 error
before resolution, but the attribute-consistent reproducer above still crashes
the same way.

(Issue filed with AI assistance.)

Contributor guide

Open the contributing guide

Research direction

Start with the reproducer and inspect ActualArgToExpr() in flang/lib/Parser/parse-tree.cpp, called from FunctionReference::ConvertToStructureConstructor. Trace how ConditionalArg reaches the conversion, then add coverage for this case and run flang -fsyntax-only repro.f90. Done means the non-conforming input emits a diagnostic instead of aborting.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, fortran
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.