[flang-commits] [flang] [flang] Improve diagnostics for mismatched intrinsic arguments (PR #221614)
via flang-commits
flang-commits at lists.llvm.org
Sun Sep 6 15:53:56 PDT 2026
https://github.com/hizyyo created https://github.com/llvm/llvm-project/pull/221614
Intrinsic arguments constrained by `KindCode::same` must have compatible types
and kinds. When this check failed, Flang reported only that the later argument
had a "bad type or kind", without identifying the earlier argument that it was
required to match.
Retain the keyword of the first `KindCode::same` argument and use it when
reporting a mismatch. The diagnostic now identifies both conflicting arguments
and their types. For example:
```text
Actual argument for 'fsource=' has type 'REAL(8)', but 'tsource=' has type 'REAL(4)'
```
This changes only the diagnostic. The intrinsic argument compatibility rules
remain unchanged.
Add a regression test for the mismatched `MERGE` arguments from #219453 and
update the affected semantic test expectations for the more specific message.
Fixes #219453.
## Testing
- Focused semantic tests: 4 passed
- `check-flang-unit`: 197 passed
- `check-flang-nongtestunit`: 10 passed
- Full Flang regression suite: 4768 passed, 11 expected failures, 228 unsupported
>From 9880cf70040332d2596174be03c82aec7f0ec9e8 Mon Sep 17 00:00:00 2001
From: hizyyo <kapolol2266 at gmail.com>
Date: Sun, 6 Sep 2026 20:23:39 +0500
Subject: [PATCH] [flang] Improve diagnostics for mismatched intrinsic
arguments
---
flang/lib/Evaluate/intrinsics.cpp | 9 +++++++++
flang/test/Semantics/bug124976.f90 | 12 ++++++------
flang/test/Semantics/bug219453.f90 | 10 ++++++++++
flang/test/Semantics/move_alloc.f90 | 2 +-
flang/test/Semantics/reshape.f90 | 4 ++--
5 files changed, 28 insertions(+), 9 deletions(-)
create mode 100644 flang/test/Semantics/bug219453.f90
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index abfb48e5ad82b..32f61d928bd01 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -2050,6 +2050,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
// (or compatible) type and kind do so. Check for missing non-optional
// arguments now, too.
const ActualArgument *sameArg{nullptr};
+ const char *sameArgName{nullptr};
const ActualArgument *operandArg{nullptr};
const IntrinsicDummyArgument *kindDummyArg{nullptr};
const ActualArgument *kindArg{nullptr};
@@ -2237,6 +2238,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
case KindCode::same: {
if (!sameArg) {
sameArg = arg;
+ sameArgName = d.keyword;
}
auto sameType{sameArg->GetType().value()};
if (name == "move_alloc"s) {
@@ -2248,6 +2250,13 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
} else {
argOk = sameType.IsTkLenCompatibleWith(*type);
}
+ if (!argOk) {
+ CHECK(sameArgName);
+ messages.Say(arg->sourceLocation(),
+ "Actual argument for '%s=' has type '%s', but '%s=' has type '%s'"_err_en_US,
+ d.keyword, type->AsFortran(), sameArgName, sameType.AsFortran());
+ return std::nullopt;
+ }
} break;
case KindCode::sameKind:
if (!sameArg) {
diff --git a/flang/test/Semantics/bug124976.f90 b/flang/test/Semantics/bug124976.f90
index 29c21d4ead847..eb53c139440a8 100644
--- a/flang/test/Semantics/bug124976.f90
+++ b/flang/test/Semantics/bug124976.f90
@@ -11,22 +11,22 @@ program main
logical var(1)
common /blk/ var
allocate(c1(2), c2(2,2), b1(2), b2(2,2))
- !ERROR: Actual argument for 'pad=' has bad type or kind 'CLASS(base)'
+ !ERROR: Actual argument for 'pad=' has type 'CLASS(base)', but 'source=' has type 'CLASS(child)'
c2 = reshape(c1, shape(c2), pad=b1)
b2 = reshape(b1, shape(b2), pad=c1) ! ok
- !ERROR: Actual argument for 'to=' has bad type or kind 'CLASS(child)'
+ !ERROR: Actual argument for 'to=' has type 'CLASS(child)', but 'from=' has type 'CLASS(base)'
call move_alloc(b1, c1)
call move_alloc(c1, b1) ! ok
- !ERROR: Actual argument for 'boundary=' has bad type or kind 'CLASS(base)'
+ !ERROR: Actual argument for 'boundary=' has type 'CLASS(base)', but 'array=' has type 'CLASS(child)'
c1 = eoshift(c1, 1, b1(1))
c1 = eoshift(c1, 1, c2(1,1)) ! ok
b1 = eoshift(b1, 1, c1(1)) ! ok
- !ERROR: Actual argument for 'fsource=' has bad type or kind 'CLASS(child)'
+ !ERROR: Actual argument for 'fsource=' has type 'CLASS(child)', but 'tsource=' has type 'CLASS(base)'
b1 = merge(b1, c1, var(1))
- !ERROR: Actual argument for 'fsource=' has bad type or kind 'CLASS(base)'
+ !ERROR: Actual argument for 'fsource=' has type 'CLASS(base)', but 'tsource=' has type 'CLASS(child)'
b1 = merge(c1, b1, var(1))
b1 = merge(b1, b1, var(1)) ! ok
- !ERROR: Actual argument for 'vector=' has bad type or kind 'CLASS(base)'
+ !ERROR: Actual argument for 'vector=' has type 'CLASS(base)', but 'array=' has type 'CLASS(child)'
c1 = pack(c1, var, b1)
c1 = pack(c1, var, c1) ! ok
b1 = pack(b1, var, c1) ! ok
diff --git a/flang/test/Semantics/bug219453.f90 b/flang/test/Semantics/bug219453.f90
new file mode 100644
index 0000000000000..976ea1fa43040
--- /dev/null
+++ b/flang/test/Semantics/bug219453.f90
@@ -0,0 +1,10 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+
+program bug219453
+ real(8) :: fsource
+ logical :: mask
+ real :: result
+
+ !ERROR: Actual argument for 'fsource=' has type 'REAL(8)', but 'tsource=' has type 'REAL(4)'
+ result = merge(1.0, fsource, mask)
+end program
diff --git a/flang/test/Semantics/move_alloc.f90 b/flang/test/Semantics/move_alloc.f90
index 73db594129eab..bbbbb0b87fc1e 100644
--- a/flang/test/Semantics/move_alloc.f90
+++ b/flang/test/Semantics/move_alloc.f90
@@ -65,7 +65,7 @@ program main
call move_alloc(t1, t2)
call move_alloc(t2, t1) ! ok
- !ERROR: Actual argument for 'to=' has bad type or kind 'CHARACTER(KIND=1,LEN=3_8)'
+ !ERROR: Actual argument for 'to=' has type 'CHARACTER(KIND=1,LEN=3_8)', but 'from=' has type 'CHARACTER(KIND=1,LEN=2_8)'
call move_alloc(ca, cb)
!ERROR: Argument #1 to MOVE_ALLOC must be allocatable
diff --git a/flang/test/Semantics/reshape.f90 b/flang/test/Semantics/reshape.f90
index 3f3b28a43569f..1a2cee5f190fd 100644
--- a/flang/test/Semantics/reshape.f90
+++ b/flang/test/Semantics/reshape.f90
@@ -16,9 +16,9 @@ program reshaper
integer :: array6(2,3) = RESHAPE([(n, n=1,6)], RESHAPE([(n, n=1,6)], [2,3]))
!ERROR: 'shape=' argument must be an array of rank 1
integer :: array7(2,3) = RESHAPE([(n, n=1,4)], 343)
- !ERROR: Actual argument for 'pad=' has bad type or kind 'INTEGER(8)'
+ !ERROR: Actual argument for 'pad=' has type 'INTEGER(8)', but 'source=' has type 'INTEGER(4)'
integer :: array8(2,3) = RESHAPE([(n, n=1,4)], [2,3], [99_8])
- !ERROR: Actual argument for 'pad=' has bad type or kind 'REAL(4)'
+ !ERROR: Actual argument for 'pad=' has type 'REAL(4)', but 'source=' has type 'INTEGER(4)'
real :: array9(2,3) = RESHAPE([(n, n=1,4)], [2,3], [99.9])
!ERROR: Invalid 'order=' argument ([INTEGER(4)::2_4,3_4]) in RESHAPE
real :: array10(2,3) = RESHAPE([(n,n=1,4)],[2,3],[99],[2,3])
More information about the flang-commits
mailing list