aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Evaluate/intrinsics.cpp
diff options
context:
space:
mode:
authorYi Wu <43659785+yi-wu-arm@users.noreply.github.com>2024-01-29 11:13:25 +0000
committerGitHub <noreply@github.com>2024-01-29 11:13:25 +0000
commit14a15103cc9dbdb3e95c04627e0b96b5e3aa4944 (patch)
treec6c8360c81dd35727b239fa23c4b6ad25fc607cf /flang/lib/Evaluate/intrinsics.cpp
parent2e2b6b53f5f63179b52168ee156df7c76b90bc71 (diff)
downloadllvm-14a15103cc9dbdb3e95c04627e0b96b5e3aa4944.zip
llvm-14a15103cc9dbdb3e95c04627e0b96b5e3aa4944.tar.gz
llvm-14a15103cc9dbdb3e95c04627e0b96b5e3aa4944.tar.bz2
Apply kind code check on exitstat and cmdstat (#78286)
When testing on gcc, both exitstat and cmdstat must be a kind=4 integer, e.g. DefaultInt. This patch changes the input arg requirement from `AnyInt` to `TypePattern{IntType, KindCode::greaterOrEqualToKind, n}`. The standard stated in 16.9.73 - EXITSTAT (optional) shall be a scalar of type integer with a decimal exponent range of at least nine. - CMDSTAT (optional) shall be a scalar of type integer with a decimal exponent range of at least four. ```fortran program bug implicit none integer(kind = 2) :: exitstatvar integer(kind = 4) :: cmdstatvar character(len=256) :: msg character(len=:), allocatable :: command command='echo hello' call execute_command_line(command, exitstat=exitstatvar, cmdstat=cmdstatvar) end program ``` When testing the above program with exitstatvar kind<4, an error would occur: ``` $ ../build-release/bin/flang-new test.f90 error: Semantic errors in test.f90 ./test.f90:8:47: error: Actual argument for 'exitstat=' has bad type or kind 'INTEGER(2)' call execute_command_line(command, exitstat=exitstatvar) ``` When testing the above program with exitstatvar kind<2, an error would occur: ``` $ ../build-release/bin/flang-new test.f90 error: Semantic errors in test.f90 ./test.f90:8:47: error: Actual argument for 'cmdstat=' has bad type or kind 'INTEGER(1)' call execute_command_line(command, cmdstat=cmdstatvar) ``` Test file for this semantics has been added to `flang/test/Semantic` Fixes: https://github.com/llvm/llvm-project/issues/77990
Diffstat (limited to 'flang/lib/Evaluate/intrinsics.cpp')
-rw-r--r--flang/lib/Evaluate/intrinsics.cpp21
1 files changed, 14 insertions, 7 deletions
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index fea8180..10e66d7 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -78,6 +78,8 @@ static constexpr CategorySet AnyType{IntrinsicType | DerivedType};
ENUM_CLASS(KindCode, none, defaultIntegerKind,
defaultRealKind, // is also the default COMPLEX kind
doublePrecision, defaultCharKind, defaultLogicalKind,
+ greaterOrEqualToKind, // match kind value greater than or equal to a single
+ // explicit kind value
any, // matches any kind value; each instance is independent
// match any kind, but all "same" kinds must be equal. For characters, also
// implies that lengths must be equal.
@@ -104,7 +106,7 @@ ENUM_CLASS(KindCode, none, defaultIntegerKind,
struct TypePattern {
CategorySet categorySet;
KindCode kindCode{KindCode::none};
- int exactKindValue{0}; // for KindCode::exactKind
+ int kindValue{0}; // for KindCode::exactKind and greaterOrEqualToKind
llvm::raw_ostream &Dump(llvm::raw_ostream &) const;
};
@@ -1320,10 +1322,11 @@ static const IntrinsicInterface intrinsicSubroutine[]{
{"execute_command_line",
{{"command", DefaultChar, Rank::scalar},
{"wait", AnyLogical, Rank::scalar, Optionality::optional},
- {"exitstat", AnyInt, Rank::scalar, Optionality::optional,
- common::Intent::InOut},
- {"cmdstat", AnyInt, Rank::scalar, Optionality::optional,
- common::Intent::Out},
+ {"exitstat",
+ TypePattern{IntType, KindCode::greaterOrEqualToKind, 4},
+ Rank::scalar, Optionality::optional, common::Intent::InOut},
+ {"cmdstat", TypePattern{IntType, KindCode::greaterOrEqualToKind, 2},
+ Rank::scalar, Optionality::optional, common::Intent::Out},
{"cmdmsg", DefaultChar, Rank::scalar, Optionality::optional,
common::Intent::InOut}},
{}, Rank::elemental, IntrinsicClass::impureSubroutine},
@@ -1856,7 +1859,10 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
argOk = true;
break;
case KindCode::exactKind:
- argOk = type->kind() == d.typePattern.exactKindValue;
+ argOk = type->kind() == d.typePattern.kindValue;
+ break;
+ case KindCode::greaterOrEqualToKind:
+ argOk = type->kind() >= d.typePattern.kindValue;
break;
case KindCode::sameAtom:
if (!sameArg) {
@@ -2199,8 +2205,9 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
resultType = DynamicType{
GetBuiltinDerivedType(builtinsScope, "__builtin_team_type")};
break;
+ case KindCode::greaterOrEqualToKind:
case KindCode::exactKind:
- resultType = DynamicType{*category, result.exactKindValue};
+ resultType = DynamicType{*category, result.kindValue};
break;
case KindCode::typeless:
case KindCode::any: