Skip to content

[flang/flang-rt] Implement PERROR intrinsic form GNU Extension #132406

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

JDPailleux
Copy link
Contributor

Add the implementation of the PERROR(STRING) intrinsic from the GNU Extension to prints on the stderr a newline-terminated error message corresponding to the last system error prefixed by STRING.
(https://gcc.gnu.org/onlinedocs/gfortran/PERROR.html)

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Mar 21, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 21, 2025

@llvm/pr-subscribers-flang-semantics

@llvm/pr-subscribers-flang-fir-hlfir

Author: Jean-Didier PAILLEUX (JDPailleux)

Changes

Add the implementation of the PERROR(STRING) intrinsic from the GNU Extension to prints on the stderr a newline-terminated error message corresponding to the last system error prefixed by STRING.
(https://gcc.gnu.org/onlinedocs/gfortran/PERROR.html)


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

4 Files Affected:

  • (modified) flang-rt/lib/runtime/extensions.cpp (+4)
  • (modified) flang/docs/Intrinsics.md (+12)
  • (modified) flang/include/flang/Runtime/extensions.h (+3)
  • (added) flang/test/Lower/Intrinsics/perror.f90 (+14)
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index 75195c33a6c21..c2d47a13d52dd 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -17,6 +17,7 @@
 #include "flang/Runtime/entry-names.h"
 #include "flang/Runtime/io-api.h"
 #include <chrono>
+#include <cstdio>
 #include <cstring>
 #include <ctime>
 #include <signal.h>
@@ -262,5 +263,8 @@ int RTNAME(Chdir)(const char *name) {
 
 int FORTRAN_PROCEDURE_NAME(ierrno)() { return errno; }
 
+// PERROR(STRING)
+void FORTRAN_PROCEDURE_NAME(perror)(const char *str) { perror(str); }
+
 } // namespace Fortran::runtime
 } // extern "C"
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index 5b671d1b2c740..2b5c3bc2fd089 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -1106,3 +1106,15 @@ end program chdir_func
 - **Standard:** GNU extension
 - **Class:** function
 - **Syntax:** `RESULT = IERRNO()`
+
+### Non-Standard Intrinsics: PERROR
+
+#### Description
+`PERROR(STRING)` prints (on the C stderr stream) a newline-terminated error message corresponding to the last system error.
+This is prefixed by `STRING`, a colon and a space.
+
+#### Usage and Info
+
+- **Standard:** GNU extension
+- **Class:** subroutine
+- **Syntax:** `CALL PERROR(STRING)`
diff --git a/flang/include/flang/Runtime/extensions.h b/flang/include/flang/Runtime/extensions.h
index 133194dea87cf..b218b9b97ce10 100644
--- a/flang/include/flang/Runtime/extensions.h
+++ b/flang/include/flang/Runtime/extensions.h
@@ -75,5 +75,8 @@ int RTNAME(Chdir)(const char *name);
 // GNU extension function IERRNO()
 int FORTRAN_PROCEDURE_NAME(ierrno)();
 
+// GNU extension subroutine PERROR(STRING)
+void FORTRAN_PROCEDURE_NAME(perror)(const char *str);
+
 } // extern "C"
 #endif // FORTRAN_RUNTIME_EXTENSIONS_H_
diff --git a/flang/test/Lower/Intrinsics/perror.f90 b/flang/test/Lower/Intrinsics/perror.f90
new file mode 100644
index 0000000000000..e42c109f6491c
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/perror.f90
@@ -0,0 +1,14 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck --check-prefixes=CHECK %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck --check-prefixes=CHECK %s
+
+! CHECK-LABEL: func @_QPtest_perror(
+subroutine test_perror()
+  character(len=10) :: string
+  call perror(string)
+  ! CHECK: %[[C10:.*]] = arith.constant 10 : index
+  ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.char<1,10> {bindc_name = "string", uniq_name = "_QFtest_perrorEstring"}
+  ! CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] typeparams %[[C10]] {uniq_name = "_QFtest_perrorEstring"} : (!fir.ref<!fir.char<1,10>>, index) -> !fir.ref<!fir.char<1,10>>
+  ! CHECK: %[[VAL_2:.*]] = fir.emboxchar %[[VAL_1]], %[[C10]] : (!fir.ref<!fir.char<1,10>>, index) -> !fir.boxchar<1>
+  ! CHECK: fir.call @_QPperror(%[[VAL_2]]) fastmath<contract> : (!fir.boxchar<1>) -> () 
+  ! CHECK: return
+end subroutine test_perror

@JDPailleux JDPailleux force-pushed the jdp/flang/perror-intrisic-gnu-extension branch from 5df86da to 0e6e0e2 Compare March 21, 2025 14:56
@JDPailleux JDPailleux requested review from jeanPerier and tblah and removed request for jeanPerier March 21, 2025 14:58
Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this intrinsic

@JDPailleux JDPailleux force-pushed the jdp/flang/perror-intrisic-gnu-extension branch from 0e6e0e2 to 6c98e32 Compare March 31, 2025 09:17
Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. LGTM.

nit: please could you add a test where the box_addr is not canonicalized away? I think using a string as a subroutine argument where the length is not known at compile time should work.

@JDPailleux JDPailleux force-pushed the jdp/flang/perror-intrisic-gnu-extension branch from 6c98e32 to 005aa9c Compare April 1, 2025 07:02
@JDPailleux
Copy link
Contributor Author

@tblah Thanks ! Test added for a string as a subroutine argument where the length is not known.

@JDPailleux JDPailleux force-pushed the jdp/flang/perror-intrisic-gnu-extension branch from 005aa9c to dd969b6 Compare April 1, 2025 07:13
Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. The new comment is a nit, feel free to merge without further approval once it is done.

Comment on lines 1 to 2
! RUN: bbc -emit-fir %s -o - | FileCheck --check-prefixes=CHECK %s
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck --check-prefixes=CHECK %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh sorry I didn't notice this before, please could you use -emit-hlfir and regenerate the test checks?

We test lowering to HLFIR separately from conversion from HLFIR to FIR so that each lit test is only checking one thing at a time. It makes it easier to see how the code changes added here are reflected in the pipeline if we aren't looking at a version that already had several complex passes run on it.

@JDPailleux JDPailleux force-pushed the jdp/flang/perror-intrisic-gnu-extension branch from dd969b6 to c500102 Compare April 1, 2025 13:08
@JDPailleux JDPailleux merged commit 513a91a into llvm:main Apr 1, 2025
12 checks passed
@@ -268,5 +269,8 @@ void FORTRAN_PROCEDURE_NAME(qsort)(int *array, int *len, int *isize,
qsort(array, *len, *isize, compar);
}

// PERROR(STRING)
void RTNAME(Perror)(const char *str) { perror(str); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code assumes that the Fortran character value is NUL-terminated, and ignores its length. The GNU documentation for PERROR does not require NUL termination.

Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request Apr 2, 2025
…132406)

Add the implementation of the `PERROR(STRING) ` intrinsic from the GNU
Extension to prints on the stderr a newline-terminated error message
corresponding to the last system error prefixed by `STRING`.
(https://gcc.gnu.org/onlinedocs/gfortran/PERROR.html)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants