[flang-commits] [flang] flang: allow EXIT to accept integer arguments of any kind (PR #174610)
via flang-commits
flang-commits at lists.llvm.org
Tue Jan 6 07:38:19 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: jay0x (blazie2004)
<details>
<summary>Changes</summary>
### Overview
This change removes a strict semantic check for the EXIT intrinsic in Flang and allows the STATUS argument to be an INTEGER of any kind, similar to gfortran and Cray Fortran.
### Problem
Flang currently rejects calls such as:
integer(8) :: status
call exit(status)
with a semantic error indicating an invalid integer kind. Other major Fortran
compilers accept this code and implicitly convert the argument to the default
integer kind.
Although Flang already performs the required conversion during lowering, the
call is rejected earlier during intrinsic interface matching.
### Solution
This PR:
- Relaxes intrinsic argument matching for `EXIT` to accept any INTEGER kind
- Preserves explicit conversion to default integer kind during lowering
### Files Modified
- flang/lib/Evaluate/intrinsics.cpp
- flang/lib/Optimizer/Builder/IntrinsicCall.cpp
---
Full diff: https://github.com/llvm/llvm-project/pull/174610.diff
2 Files Affected:
- (modified) flang/lib/Evaluate/intrinsics.cpp (+12-3)
- (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+7-2)
``````````diff
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) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/174610
More information about the flang-commits
mailing list