[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