[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