[flang-commits] [flang] [flang] Improve intrinsic error messages when multiple signatures exist (PR #172099)

via flang-commits flang-commits at lists.llvm.org
Mon Dec 15 13:46:21 PST 2025


https://github.com/tmjbios updated https://github.com/llvm/llvm-project/pull/172099

>From a55b0a94071201c066bde0925930763670864a1f Mon Sep 17 00:00:00 2001
From: Ted Johnson <tedj at hpe.com>
Date: Fri, 12 Dec 2025 18:25:58 +0000
Subject: [PATCH 1/2] [flang] Improve intrinsic error messages when multiple
 signatures exist

When an intrinsic has multiple table entries (e.g., BESSEL_JN has both
elemental and transformational forms), the error message selection
logic now prefers specific argument errors over generic "too many
actual arguments" messages.

For example, given:

    real, dimension(10) :: xarray
    integer :: n1, n2
    print *, bessel_jn(n1, n2, xarray)

The transformational form of BESSEL_JN(n1, n2, x) requires x to be
scalar. Previously, flang reported "too many actual arguments" from
the elemental form (which only accepts 2 args), even though the
transformational form matched the argument count but failed on rank.

Now flang correctly reports "'x=' argument has unacceptable rank 1",
which better guides the user to the actual problem.

The fix extends the error buffer selection heuristic in Probe() to
prefer later table entries when earlier entries fail with argument
count mismatches.
---
 flang/lib/Evaluate/intrinsics.cpp     | 18 ++++++++++++++++--
 flang/test/Semantics/bessel_jn.f90    | 25 +++++++++++++++++++++++++
 flang/test/Semantics/num_images01.f90 |  3 +--
 flang/test/Semantics/num_images02.f90 |  2 +-
 4 files changed, 43 insertions(+), 5 deletions(-)
 create mode 100644 flang/test/Semantics/bessel_jn.f90

diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index da39f199cab43..30757de167d3c 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -3597,8 +3597,13 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
           // presence of DIM=, use messages from a later entry if
           // the messages from an earlier entry complain about the
           // DIM= argument and it wasn't specified with a keyword.
+          // Also prefer later messages when earlier ones are about
+          // argument count mismatches, as a later entry that accepts
+          // the right number of arguments will give more specific errors.
+          bool dominated{false};
           for (const auto &m : buffer.messages()) {
-            if (m.ToString().find("'dim='") != std::string::npos) {
+            std::string text{m.ToString()};
+            if (text.find("'dim='") != std::string::npos) {
               bool hadDimKeyword{false};
               for (const auto &a : arguments) {
                 if (a) {
@@ -3609,11 +3614,20 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
                 }
               }
               if (!hadDimKeyword) {
-                buffer = std::move(localBuffer);
+                dominated = true;
               }
               break;
+            } else if (text.find("too many actual arguments") !=
+                std::string::npos) {
+              // Prefer messages from an entry that matched the argument
+              // count, as those will be more specific about what's wrong
+              dominated = true;
+              break;
             }
           }
+          if (dominated) {
+            buffer = std::move(localBuffer);
+          }
           localBuffer.clear();
         }
         return std::nullopt;
diff --git a/flang/test/Semantics/bessel_jn.f90 b/flang/test/Semantics/bessel_jn.f90
new file mode 100644
index 0000000000000..e94a6db44e09c
--- /dev/null
+++ b/flang/test/Semantics/bessel_jn.f90
@@ -0,0 +1,25 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! Test semantic checking for BESSEL_JN and BESSEL_YN intrinsics
+
+program test_bessel
+  real :: x, result_scalar
+  real :: xarray(10), result_array(10)
+  integer :: n, n1, n2
+
+  ! Valid elemental forms
+  result_scalar = bessel_jn(n, x)
+  result_scalar = bessel_yn(n, x)
+  result_array = bessel_jn(n, xarray)
+  result_array = bessel_yn(n, xarray)
+
+  ! Valid transformational forms (x must be scalar)
+  result_array(n1:n2) = bessel_jn(n1, n2, x)
+  result_array(n1:n2) = bessel_yn(n1, n2, x)
+
+  ! Invalid: transformational form with array x
+  !ERROR: 'x=' argument has unacceptable rank 1
+  result_array(n1:n2) = bessel_jn(n1, n2, xarray)
+
+  !ERROR: 'x=' argument has unacceptable rank 1
+  result_array(n1:n2) = bessel_yn(n1, n2, xarray)
+end program
diff --git a/flang/test/Semantics/num_images01.f90 b/flang/test/Semantics/num_images01.f90
index 37f360b2c691e..29d54ee840760 100644
--- a/flang/test/Semantics/num_images01.f90
+++ b/flang/test/Semantics/num_images01.f90
@@ -15,8 +15,7 @@ subroutine test
   print *, num_images(team=my_team)
 
   ! incorrectly typed argument
-  ! the error is seen as too many arguments to the num_images() call with no arguments
-  !ERROR: too many actual arguments for intrinsic 'num_images'
+  !ERROR: Actual argument for 'team=' has bad type 'REAL(4)'
   print *, num_images(3.4)
 
   ! call with too many arguments
diff --git a/flang/test/Semantics/num_images02.f90 b/flang/test/Semantics/num_images02.f90
index fb052644c9524..68dccb13f6d70 100644
--- a/flang/test/Semantics/num_images02.f90
+++ b/flang/test/Semantics/num_images02.f90
@@ -36,7 +36,7 @@ program num_images_with_team_type
   n = num_images(team=league)
 
   ! incorrectly typed argument
-  !ERROR: too many actual arguments for intrinsic 'num_images'
+  !ERROR: Actual argument for 'team=' has bad type 'REAL(4)'
   n = num_images(3.4)
 
   !ERROR: too many actual arguments for intrinsic 'num_images'

>From a2847114b0671a0ed43f28e207e5036b196ae558 Mon Sep 17 00:00:00 2001
From: Ted Johnson <tedj at hpe.com>
Date: Mon, 15 Dec 2025 14:44:25 -0700
Subject: [PATCH 2/2] Use a more descriptive name for local variable.

The initial name for a local bool wasn't very descriptive.
Update to use preferLaterError as suggested by akuhlens.
---
 flang/lib/Evaluate/intrinsics.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 30757de167d3c..72ac9e2f68758 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -3600,7 +3600,7 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
           // Also prefer later messages when earlier ones are about
           // argument count mismatches, as a later entry that accepts
           // the right number of arguments will give more specific errors.
-          bool dominated{false};
+          bool preferLaterError{false};
           for (const auto &m : buffer.messages()) {
             std::string text{m.ToString()};
             if (text.find("'dim='") != std::string::npos) {
@@ -3614,18 +3614,18 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
                 }
               }
               if (!hadDimKeyword) {
-                dominated = true;
+                preferLaterError = true;
               }
               break;
             } else if (text.find("too many actual arguments") !=
                 std::string::npos) {
               // Prefer messages from an entry that matched the argument
               // count, as those will be more specific about what's wrong
-              dominated = true;
+              preferLaterError = true;
               break;
             }
           }
-          if (dominated) {
+          if (preferLaterError) {
             buffer = std::move(localBuffer);
           }
           localBuffer.clear();



More information about the flang-commits mailing list