[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:54:49 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Eugene (hizyyo)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/221614.diff


5 Files Affected:

- (modified) flang/lib/Evaluate/intrinsics.cpp (+9) 
- (modified) flang/test/Semantics/bug124976.f90 (+6-6) 
- (added) flang/test/Semantics/bug219453.f90 (+10) 
- (modified) flang/test/Semantics/move_alloc.f90 (+1-1) 
- (modified) flang/test/Semantics/reshape.f90 (+2-2) 


``````````diff
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])

``````````

</details>


https://github.com/llvm/llvm-project/pull/221614


More information about the flang-commits mailing list