[flang-commits] [flang] flang: allow EXIT to accept integer arguments of any kind (PR #174610)

via flang-commits flang-commits at lists.llvm.org
Mon Jan 19 08:55:45 PST 2026


https://github.com/blazie2004 updated https://github.com/llvm/llvm-project/pull/174610

>From 083a655a22da3558d34f149266246e944031f0bb Mon Sep 17 00:00:00 2001
From: Jay Satish Kumar Patel <kumarpat at pe31.hpc.amslabs.hpecorp.net>
Date: Tue, 6 Jan 2026 09:28:25 -0600
Subject: [PATCH 1/3] flang: allow EXIT to accept integer arguments of any kind

---
 flang/lib/Evaluate/intrinsics.cpp             | 15 ++++++++++++---
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp |  9 +++++++--
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index da39f199cab43..2e22819ce4e30 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -1604,7 +1604,7 @@ static const IntrinsicInterface intrinsicSubroutine[]{
             {"cmdmsg", DefaultChar, Rank::scalar, Optionality::optional,
                 common::Intent::InOut}},
         {}, Rank::elemental, IntrinsicClass::impureSubroutine},
-    {"exit", {{"status", DefaultInt, Rank::scalar, Optionality::optional}}, {},
+    {"exit", {{"status", AnyInt, Rank::scalar, Optionality::optional}}, {},
         Rank::elemental, IntrinsicClass::impureSubroutine},
     {"free", {{"ptr", Addressable}}, {}},
     {"flush",
@@ -2157,8 +2157,16 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
           semantics::IsTeamType(&type->GetDerivedTypeSpec());
       break;
     case KindCode::defaultIntegerKind:
-      argOk = type->kind() == defaults.GetDefaultKind(TypeCategory::Integer);
-      break;
+  if (name == "exit" && d.keyword == "status" &&
+      type->category() == TypeCategory::Integer) {
+    // GNU / CCE compatibility: allow any integer kind
+    argOk = true;
+  } else {
+    argOk = type->kind() ==
+        defaults.GetDefaultKind(TypeCategory::Integer);
+  }
+  break;
+
     case KindCode::defaultRealKind:
       argOk = type->kind() == defaults.GetDefaultKind(TypeCategory::Real);
       break;
@@ -2286,6 +2294,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
           d.keyword, type->AsFortran());
       return std::nullopt;
     }
+    
   }
 
   // Check the ranks of the arguments against the intrinsic's interface.
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 75a74eeb18417..ccf500f852fbf 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -3852,12 +3852,17 @@ void IntrinsicLibrary::genExit(llvm::ArrayRef<fir::ExtendedValue> args) {
                                           EXIT_SUCCESS)
           : fir::getBase(args[0]);
 
-  assert(status.getType() == builder.getDefaultIntegerType() &&
-         "STATUS parameter must be an INTEGER of default kind");
+  mlir::Type defaultIntTy = builder.getDefaultIntegerType();
+
+  // Convert INTEGER(any kind) → default INTEGER
+  if (status.getType() != defaultIntTy) {
+    status = builder.createConvert(loc, defaultIntTy, status);
+  }
 
   fir::runtime::genExit(builder, loc, status);
 }
 
+
 // EXPONENT
 mlir::Value IntrinsicLibrary::genExponent(mlir::Type resultType,
                                           llvm::ArrayRef<mlir::Value> args) {

>From 48b34887bfbf8c2828b321621bfc002df4e79ede Mon Sep 17 00:00:00 2001
From: Jay Satish Kumar Patel <kumarpat at pe31.hpc.amslabs.hpecorp.net>
Date: Sun, 11 Jan 2026 11:32:36 -0600
Subject: [PATCH 2/3] flang: update EXIT intrinsic argument matching

---
 flang/lib/Evaluate/intrinsics.cpp             | 24 ++++++-------------
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 10 +++++---
 flang/test/Semantics/exit-nondefault-kind.f90 | 16 +++++++++++++
 3 files changed, 30 insertions(+), 20 deletions(-)
 create mode 100644 flang/test/Semantics/exit-nondefault-kind.f90

diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 2e22819ce4e30..5e8f4b1c3c93c 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -1914,7 +1914,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
   // arguments in a procedure reference.
   std::size_t dummyArgPatterns{0};
   for (; dummyArgPatterns < maxArguments && dummy[dummyArgPatterns].keyword;
-       ++dummyArgPatterns) {
+      ++dummyArgPatterns) {
   }
   // MAX and MIN (and others that map to them) allow their last argument to
   // be repeated indefinitely.  The actualForDummy vector is sized
@@ -2157,16 +2157,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
           semantics::IsTeamType(&type->GetDerivedTypeSpec());
       break;
     case KindCode::defaultIntegerKind:
-  if (name == "exit" && d.keyword == "status" &&
-      type->category() == TypeCategory::Integer) {
-    // GNU / CCE compatibility: allow any integer kind
-    argOk = true;
-  } else {
-    argOk = type->kind() ==
-        defaults.GetDefaultKind(TypeCategory::Integer);
-  }
-  break;
-
+      argOk = type->kind() == defaults.GetDefaultKind(TypeCategory::Integer);
+      break;
     case KindCode::defaultRealKind:
       argOk = type->kind() == defaults.GetDefaultKind(TypeCategory::Real);
       break;
@@ -2294,9 +2286,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
           d.keyword, type->AsFortran());
       return std::nullopt;
     }
-    
   }
-
   // Check the ranks of the arguments against the intrinsic's interface.
   const ActualArgument *arrayArg{nullptr};
   const char *arrayArgName{nullptr};
@@ -2748,7 +2738,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
   // Rearrange the actual arguments into dummy argument order.
   ActualArguments rearranged(dummies);
   for (std::size_t j{0}; j < dummies; ++j) {
-    if (ActualArgument *arg{actualForDummy[j]}) {
+    if (ActualArgument * arg{actualForDummy[j]}) {
       rearranged[j] = std::move(*arg);
     }
   }
@@ -3645,7 +3635,7 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
   parser::Messages specificBuffer;
   auto specificRange{specificFuncs_.equal_range(call.name)};
   for (auto specIter{specificRange.first}; specIter != specificRange.second;
-       ++specIter) {
+      ++specIter) {
     // We only need to check the cases with distinct generic names.
     if (const char *genericName{specIter->second->generic}) {
       if (auto specificCall{
@@ -3667,13 +3657,13 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
   if (context.languageFeatures().IsEnabled(common::LanguageFeature::
               UseGenericIntrinsicWhenSpecificDoesntMatch)) {
     for (auto specIter{specificRange.first}; specIter != specificRange.second;
-         ++specIter) {
+        ++specIter) {
       // We only need to check the cases with distinct generic names.
       if (const char *genericName{specIter->second->generic}) {
         if (specIter->second->useGenericAndForceResultType) {
           auto genericRange{genericFuncs_.equal_range(genericName)};
           for (auto genIter{genericRange.first}; genIter != genericRange.second;
-               ++genIter) {
+              ++genIter) {
             if (auto specificCall{
                     matchOrBufferMessages(*genIter->second, specificBuffer)}) {
               // Force the call result type to the specific intrinsic result
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index ccf500f852fbf..7018ff79f7f04 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -2293,7 +2293,6 @@ bool static hasAbsentOptional(llvm::ArrayRef<fir::ExtendedValue> args) {
       return true;
   return false;
 }
-
 template <typename GeneratorType>
 mlir::Value
 IntrinsicLibrary::outlineInWrapper(GeneratorType generator,
@@ -3854,6 +3853,13 @@ void IntrinsicLibrary::genExit(llvm::ArrayRef<fir::ExtendedValue> args) {
 
   mlir::Type defaultIntTy = builder.getDefaultIntegerType();
 
+  // Warn about non-default integer kinds with -pedantic
+  if (status.getType() != defaultIntTy) {
+    mlir::emitWarning(
+        loc,
+        "EXIT intrinsic with non-default INTEGER kind is a language extension");
+  }
+
   // Convert INTEGER(any kind) → default INTEGER
   if (status.getType() != defaultIntTy) {
     status = builder.createConvert(loc, defaultIntTy, status);
@@ -3861,8 +3867,6 @@ void IntrinsicLibrary::genExit(llvm::ArrayRef<fir::ExtendedValue> args) {
 
   fir::runtime::genExit(builder, loc, status);
 }
-
-
 // EXPONENT
 mlir::Value IntrinsicLibrary::genExponent(mlir::Type resultType,
                                           llvm::ArrayRef<mlir::Value> args) {
diff --git a/flang/test/Semantics/exit-nondefault-kind.f90 b/flang/test/Semantics/exit-nondefault-kind.f90
new file mode 100644
index 0000000000000..2a0424e846523
--- /dev/null
+++ b/flang/test/Semantics/exit-nondefault-kind.f90
@@ -0,0 +1,16 @@
+! Test that EXIT accepts INTEGER of any kind
+! RUN: %flang_fc1 %s
+
+program test_exit_any_integer
+  implicit none
+  integer(1) :: s1 = 1
+  integer(2) :: s2 = 2
+  integer(4) :: s4 = 4
+  integer(8) :: s8 = 8
+
+  call exit(s1)
+  call exit(s2)
+  call exit(s4)
+  call exit(s8)
+
+end program test_exit_any_integer
\ No newline at end of file

>From 6c316695e0c9fb7a993522dd3c43c6eed87cf9f6 Mon Sep 17 00:00:00 2001
From: Jay Satish Kumar Patel <kumarpat at pe31.hpc.amslabs.hpecorp.net>
Date: Mon, 19 Jan 2026 03:38:52 -0600
Subject: [PATCH 3/3] removed warning from IntrinsicCall.cpp

---
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 7018ff79f7f04..dd74de43faabf 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -3852,14 +3852,6 @@ void IntrinsicLibrary::genExit(llvm::ArrayRef<fir::ExtendedValue> args) {
           : fir::getBase(args[0]);
 
   mlir::Type defaultIntTy = builder.getDefaultIntegerType();
-
-  // Warn about non-default integer kinds with -pedantic
-  if (status.getType() != defaultIntTy) {
-    mlir::emitWarning(
-        loc,
-        "EXIT intrinsic with non-default INTEGER kind is a language extension");
-  }
-
   // Convert INTEGER(any kind) → default INTEGER
   if (status.getType() != defaultIntTy) {
     status = builder.createConvert(loc, defaultIntTy, status);



More information about the flang-commits mailing list