[flang-commits] [flang] [flang] Implement GETUID and GETGID intrinsics (PR #108017)
David Truby via flang-commits
flang-commits at lists.llvm.org
Thu Sep 26 07:05:15 PDT 2024
https://github.com/DavidTruby updated https://github.com/llvm/llvm-project/pull/108017
>From 74242efc0f374b7e35083d473cf64e9162683329 Mon Sep 17 00:00:00 2001
From: David Truby <david.truby at arm.com>
Date: Tue, 10 Sep 2024 13:55:27 +0100
Subject: [PATCH 1/4] [flang] Implement GETUID and GETGID intrinsics
GETUID and GETGID are non-standard intrinsics supported by a number of
other Fortran compilers. On supported platforms these intrinsics simply
call the POSIX getuid() and getgid() functions and return the result.
The only platform we support that does not have these is Windows.
Windows does not have the same concept of UIDs and GIDs, so on Windows
we issue a warning indicating this and return 1 from both functions.
Co-authored-by: Yi Wu <yi.wu2 at arm.com>
---
flang/docs/Intrinsics.md | 2 +-
flang/include/flang/Evaluate/target.h | 6 ++++++
.../flang/Optimizer/Builder/IntrinsicCall.h | 4 ++++
.../flang/Optimizer/Builder/Runtime/Command.h | 3 +++
flang/include/flang/Runtime/command.h | 9 +++++++++
flang/include/flang/Tools/TargetSetup.h | 3 +++
flang/lib/Evaluate/intrinsics.cpp | 2 ++
flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 18 ++++++++++++++++++
.../lib/Optimizer/Builder/Runtime/Command.cpp | 16 ++++++++++++++++
flang/lib/Semantics/check-call.cpp | 14 ++++++++++++++
flang/lib/Semantics/check-call.h | 2 ++
flang/lib/Semantics/expression.cpp | 3 +++
flang/runtime/command.cpp | 18 ++++++++++++++++++
flang/test/Semantics/windows.f90 | 12 ++++++++++++
.../Optimizer/Builder/Runtime/CommandTest.cpp | 16 +++++++++++++++-
flang/unittests/Runtime/CommandTest.cpp | 10 ++++++++++
16 files changed, 136 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Semantics/windows.f90
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index 87716731ead855..e288fdeec6cd22 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -765,7 +765,7 @@ This phase currently supports all the intrinsic procedures listed above but the
| Coarray intrinsic functions | COSHAPE |
| Object characteristic inquiry functions | ALLOCATED, ASSOCIATED, EXTENDS_TYPE_OF, IS_CONTIGUOUS, PRESENT, RANK, SAME_TYPE, STORAGE_SIZE |
| Type inquiry intrinsic functions | BIT_SIZE, DIGITS, EPSILON, HUGE, KIND, MAXEXPONENT, MINEXPONENT, NEW_LINE, PRECISION, RADIX, RANGE, TINY|
-| Non-standard intrinsic functions | AND, OR, XOR, SHIFT, ZEXT, IZEXT, COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D, COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT, QCMPLX, DREAL, DFLOAT, QEXT, QFLOAT, QREAL, DNUM, NUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN, SIZEOF, MCLOCK, SECNDS, COTAN, IBCHNG, ISHA, ISHC, ISHL, IXOR, IARG, IARGC, NARGS, GETPID, NUMARG, BADDRESS, IADDR, CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, MALLOC |
+| Non-standard intrinsic functions | AND, OR, XOR, SHIFT, ZEXT, IZEXT, COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D, COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT, QCMPLX, DREAL, DFLOAT, QEXT, QFLOAT, QREAL, DNUM, NUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN, SIZEOF, MCLOCK, SECNDS, COTAN, IBCHNG, ISHA, ISHC, ISHL, IXOR, IARG, IARGC, NARGS, GETPID, NUMARG, BADDRESS, IADDR, CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, MALLOC, GETUID, GETGID |
| Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SIGNAL, SLEEP, SYSTEM, SYSTEM_CLOCK |
| Atomic intrinsic subroutines | ATOMIC_ADD |
| Collective intrinsic subroutines | CO_REDUCE |
diff --git a/flang/include/flang/Evaluate/target.h b/flang/include/flang/Evaluate/target.h
index d076fcbf083078..b347c549e012da 100644
--- a/flang/include/flang/Evaluate/target.h
+++ b/flang/include/flang/Evaluate/target.h
@@ -102,6 +102,11 @@ class TargetCharacteristics {
bool isPPC() const { return isPPC_; }
void set_isPPC(bool isPPC = false);
+ bool isOSWindows() const { return isOSWindows_; }
+ void set_isOSWindows(bool isOSWindows = false) {
+ isOSWindows_ = isOSWindows;
+ };
+
IeeeFeatures &ieeeFeatures() { return ieeeFeatures_; }
const IeeeFeatures &ieeeFeatures() const { return ieeeFeatures_; }
@@ -111,6 +116,7 @@ class TargetCharacteristics {
std::uint8_t align_[common::TypeCategory_enumSize][maxKind]{};
bool isBigEndian_{false};
bool isPPC_{false};
+ bool isOSWindows_{false};
bool areSubnormalsFlushedToZero_{false};
Rounding roundingMode_{defaultRounding};
std::size_t procedurePointerByteSize_{8};
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 78bb82b17d4050..b2da6138fc9d8e 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -256,6 +256,10 @@ struct IntrinsicLibrary {
llvm::ArrayRef<mlir::Value> args);
void genGetCommandArgument(mlir::ArrayRef<fir::ExtendedValue> args);
void genGetEnvironmentVariable(llvm::ArrayRef<fir::ExtendedValue>);
+ mlir::Value genGetGID(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args);
+ mlir::Value genGetUID(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args);
fir::ExtendedValue genIall(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genIand(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genIany(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Command.h b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
index 0d60a367d99981..50b655a6bc9e6c 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Command.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
@@ -58,5 +58,8 @@ mlir::Value genGetEnvVariable(fir::FirOpBuilder &, mlir::Location,
mlir::Value genGetCwd(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value c);
+mlir::Value genGetUID(fir::FirOpBuilder &, mlir::Location);
+mlir::Value genGetGID(fir::FirOpBuilder &, mlir::Location);
+
} // namespace fir::runtime
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COMMAND_H
diff --git a/flang/include/flang/Runtime/command.h b/flang/include/flang/Runtime/command.h
index 7ab3f6442dcf92..e4597c480d65ea 100644
--- a/flang/include/flang/Runtime/command.h
+++ b/flang/include/flang/Runtime/command.h
@@ -15,6 +15,9 @@
#ifdef _WIN32
// On Windows* OS GetCurrentProcessId returns DWORD aka uint32_t
typedef std::uint32_t pid_t;
+// UID and GID don't exist on Windows, these exist to avoid errors.
+typedef std::uint32_t uid_t;
+typedef std::uint32_t gid_t;
#else
#include "sys/types.h" //pid_t
#endif
@@ -29,9 +32,15 @@ extern "C" {
// integer kind.
std::int32_t RTNAME(ArgumentCount)();
+// Calls getgid()
+gid_t RTNAME(GetGID)();
+
// Calls getpid()
pid_t RTNAME(GetPID)();
+// Calls getuid()
+uid_t RTNAME(GetUID)();
+
// 16.9.82 GET_COMMAND
// Try to get the value of the whole command. All of the parameters are
// optional.
diff --git a/flang/include/flang/Tools/TargetSetup.h b/flang/include/flang/Tools/TargetSetup.h
index ee89249441c174..278a7edb0ea725 100644
--- a/flang/include/flang/Tools/TargetSetup.h
+++ b/flang/include/flang/Tools/TargetSetup.h
@@ -58,6 +58,9 @@ namespace Fortran::tools {
if (targetTriple.isPPC())
targetCharacteristics.set_isPPC(true);
+ if (targetTriple.isOSWindows())
+ targetCharacteristics.set_isOSWindows(true);
+
// TODO: use target machine data layout to set-up the target characteristics
// type size and alignment info.
}
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index fcedf5ec3ddf83..7eea3848d73557 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -523,7 +523,9 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{{"c", DefaultChar, Rank::scalar, Optionality::required,
common::Intent::Out}},
TypePattern{IntType, KindCode::greaterOrEqualToKind, 4}},
+ {"getgid", {}, DefaultInt},
{"getpid", {}, DefaultInt},
+ {"getuid", {}, DefaultInt},
{"huge",
{{"x", SameIntOrReal, Rank::anyOrAssumedRank, Optionality::required,
common::Intent::In, {ArgFlag::canBeMoldNull}}},
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index dc0dc47bda9a9d..7f474238138660 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -293,7 +293,9 @@ static constexpr IntrinsicHandler handlers[]{
&I::genGetCwd,
{{{"c", asBox}, {"status", asAddr, handleDynamicOptional}}},
/*isElemental=*/false},
+ {"getgid", &I::genGetGID},
{"getpid", &I::genGetPID},
+ {"getuid", &I::genGetUID},
{"iachar", &I::genIchar},
{"iall",
&I::genIall,
@@ -3650,6 +3652,14 @@ void IntrinsicLibrary::genGetCommand(llvm::ArrayRef<fir::ExtendedValue> args) {
}
}
+// GETGID
+mlir::Value IntrinsicLibrary::genGetGID(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 0 && "getgid takes no input");
+ return builder.createConvert(loc, resultType,
+ fir::runtime::genGetGID(builder, loc));
+}
+
// GETPID
mlir::Value IntrinsicLibrary::genGetPID(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
@@ -3658,6 +3668,14 @@ mlir::Value IntrinsicLibrary::genGetPID(mlir::Type resultType,
fir::runtime::genGetPID(builder, loc));
}
+// GETUID
+mlir::Value IntrinsicLibrary::genGetUID(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 0 && "getgid takes no input");
+ return builder.createConvert(loc, resultType,
+ fir::runtime::genGetUID(builder, loc));
+}
+
// GET_COMMAND_ARGUMENT
void IntrinsicLibrary::genGetCommandArgument(
llvm::ArrayRef<fir::ExtendedValue> args) {
diff --git a/flang/lib/Optimizer/Builder/Runtime/Command.cpp b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
index 8320d89493b336..d035c9156e1e8c 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Command.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
@@ -48,6 +48,14 @@ mlir::Value fir::runtime::genGetCommand(fir::FirOpBuilder &builder,
return builder.create<fir::CallOp>(loc, runtimeFunc, args).getResult(0);
}
+mlir::Value fir::runtime::genGetGID(fir::FirOpBuilder &builder,
+ mlir::Location loc) {
+ auto runtimeFunc =
+ fir::runtime::getRuntimeFunc<mkRTKey(GetGID)>(loc, builder);
+
+ return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
+}
+
mlir::Value fir::runtime::genGetPID(fir::FirOpBuilder &builder,
mlir::Location loc) {
auto runtimeFunc =
@@ -56,6 +64,14 @@ mlir::Value fir::runtime::genGetPID(fir::FirOpBuilder &builder,
return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
}
+mlir::Value fir::runtime::genGetUID(fir::FirOpBuilder &builder,
+ mlir::Location loc) {
+ auto runtimeFunc =
+ fir::runtime::getRuntimeFunc<mkRTKey(GetUID)>(loc, builder);
+
+ return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
+}
+
mlir::Value fir::runtime::genGetCommandArgument(
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value number,
mlir::Value value, mlir::Value length, mlir::Value errmsg) {
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index c7ec8733655648..63152a62a5789a 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -2020,6 +2020,20 @@ bool CheckPPCIntrinsic(const Symbol &generic, const Symbol &specific,
return false;
}
+bool CheckWindowsIntrinsic(
+ const Symbol &intrinsic, evaluate::FoldingContext &foldingContext) {
+ parser::ContextualMessages &messages{foldingContext.messages()};
+ if (intrinsic.name() == "getuid") {
+ messages.Say(
+ "User IDs do not exist on Windows. This function will always return 1"_warn_en_US);
+ }
+ if (intrinsic.name() == "getgid") {
+ messages.Say(
+ "Group IDs do not exist on Windows. This function will always return 1"_warn_en_US);
+ }
+ return true;
+}
+
bool CheckArguments(const characteristics::Procedure &proc,
evaluate::ActualArguments &actuals, SemanticsContext &context,
const Scope &scope, bool treatingExternalAsImplicit,
diff --git a/flang/lib/Semantics/check-call.h b/flang/lib/Semantics/check-call.h
index 8553f3a31efb52..46bc61a601bd34 100644
--- a/flang/lib/Semantics/check-call.h
+++ b/flang/lib/Semantics/check-call.h
@@ -41,6 +41,8 @@ bool CheckArguments(const evaluate::characteristics::Procedure &,
bool CheckPPCIntrinsic(const Symbol &generic, const Symbol &specific,
const evaluate::ActualArguments &actuals,
evaluate::FoldingContext &context);
+bool CheckWindowsIntrinsic(
+ const Symbol &intrinsic, evaluate::FoldingContext &context);
bool CheckArgumentIsConstantExprInRange(
const evaluate::ActualArguments &actuals, int index, int lowerBound,
int upperBound, parser::ContextualMessages &messages);
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 3684839c187e68..e1484bfd0ff8fd 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -2905,6 +2905,9 @@ auto ExpressionAnalyzer::GetCalleeAndArguments(const parser::Name &name,
} else {
resolution = symbol;
}
+ if (resolution && context_.targetCharacteristics().isOSWindows()) {
+ semantics::CheckWindowsIntrinsic(*resolution, GetFoldingContext());
+ }
if (!resolution || resolution->attrs().test(semantics::Attr::INTRINSIC)) {
auto name{resolution ? resolution->name() : ultimate.name()};
if (std::optional<SpecificCall> specificCall{context_.intrinsics().Probe(
diff --git a/flang/runtime/command.cpp b/flang/runtime/command.cpp
index a555e26f96a66c..3e0bc396da4da0 100644
--- a/flang/runtime/command.cpp
+++ b/flang/runtime/command.cpp
@@ -42,8 +42,26 @@ std::int32_t RTNAME(ArgumentCount)() {
return 0;
}
+gid_t RTNAME(GetGID)() {
+#ifdef _WIN32
+ // Group IDs don't exist on Windows, return 1 to avoid errors
+ return 1;
+#else
+ return getgid();
+#endif
+}
+
pid_t RTNAME(GetPID)() { return getpid(); }
+uid_t RTNAME(GetUID)() {
+#ifdef _WIN32
+ // User IDs don't exist on Windows, return 1 to avoid errors
+ return 1;
+#else
+ return getuid();
+#endif
+}
+
// Returns the length of the \p string. Assumes \p string is valid.
static std::int64_t StringLength(const char *string) {
std::size_t length{std::strlen(string)};
diff --git a/flang/test/Semantics/windows.f90 b/flang/test/Semantics/windows.f90
new file mode 100644
index 00000000000000..8f9d1aa606c0a0
--- /dev/null
+++ b/flang/test/Semantics/windows.f90
@@ -0,0 +1,12 @@
+! RUN: %python %S/test_errors.py %s %flang --target=x86_64-pc-windows-msvc -Werror
+! RUN: %python %S/test_errors.py %s %flang --target=aarch64-pc-windows-msvc -Werror
+
+subroutine uid
+ !WARNING: User IDs do not exist on Windows. This function will always return 1
+ i = getuid()
+end subroutine uid
+
+subroutine gid
+ !WARNING: Group IDs do not exist on Windows. This function will always return 1
+ i = getgid()
+end subroutine gid
diff --git a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
index 58a151447d5b4f..12f479247a41d8 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
@@ -45,9 +45,23 @@ TEST_F(RuntimeCallTest, genGetEnvVariable) {
/*addLocArgs=*/true);
}
+TEST_F(RuntimeCallTest, genGetGID) {
+ mlir::Location loc = firBuilder->getUnknownLoc();
+ mlir::Value result = fir::runtime::genGetGID(*firBuilder, loc);
+ checkCallOp(result.getDefiningOp(), "_FortranAGetGID", /*nbArgs=*/0,
+ /*addLocArgs=*/false);
+}
+
TEST_F(RuntimeCallTest, genGetPID) {
mlir::Location loc = firBuilder->getUnknownLoc();
mlir::Value result = fir::runtime::genGetPID(*firBuilder, loc);
checkCallOp(result.getDefiningOp(), "_FortranAGetPID", /*nbArgs=*/0,
/*addLocArgs=*/false);
-}
\ No newline at end of file
+}
+
+TEST_F(RuntimeCallTest, genGetUID) {
+ mlir::Location loc = firBuilder->getUnknownLoc();
+ mlir::Value result = fir::runtime::genGetUID(*firBuilder, loc);
+ checkCallOp(result.getDefiningOp(), "_FortranAGetUID", /*nbArgs=*/0,
+ /*addLocArgs=*/false);
+}
diff --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index b0c43ba01d8f33..02e0cd94b5ef5b 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -689,11 +689,21 @@ TEST_F(OnlyValidArguments, GetCommandShortLength) {
CheckDescriptorEqInt<short>(length.get(), 51);
}
+TEST_F(ZeroArguments, GetGID) {
+ // gid cannot be negative
+ EXPECT_GE(RTNAME(GetGID)(), 0u);
+}
+
TEST_F(ZeroArguments, GetPID) {
// pid should always greater than 0, in both linux and windows
EXPECT_GT(RTNAME(GetPID)(), 0);
}
+TEST_F(ZeroArguments, GetUID) {
+ // uid cannot be negative
+ EXPECT_GE(RTNAME(GetUID)(), 0u);
+}
+
class EnvironmentVariables : public CommandFixture {
protected:
EnvironmentVariables() : CommandFixture(0, nullptr) {
>From 19a4b9eb380c352efd7208b636f92d3447de0d35 Mon Sep 17 00:00:00 2001
From: David Truby <david.truby at arm.com>
Date: Wed, 11 Sep 2024 14:16:09 +0100
Subject: [PATCH 2/4] move getuid/getpid to extensions.cpp and add TODO
---
.../Optimizer/Builder/Runtime/Intrinsics.h | 3 +++
flang/include/flang/Runtime/command.h | 9 ---------
flang/include/flang/Runtime/extensions.h | 14 ++++++++++++++
.../lib/Optimizer/Builder/Runtime/Command.cpp | 16 ----------------
.../Optimizer/Builder/Runtime/Intrinsics.cpp | 16 ++++++++++++++++
flang/lib/Semantics/check-call.cpp | 2 ++
flang/runtime/command.cpp | 18 ------------------
flang/runtime/extensions.cpp | 19 +++++++++++++++++++
8 files changed, 54 insertions(+), 43 deletions(-)
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h b/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h
index 240de5a899d37b..49d8249d6bcbce 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h
@@ -47,6 +47,9 @@ void genDateAndTime(fir::FirOpBuilder &, mlir::Location,
void genEtime(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value values, mlir::Value time);
+mlir::Value genGetUID(fir::FirOpBuilder &, mlir::Location);
+mlir::Value genGetGID(fir::FirOpBuilder &, mlir::Location);
+
void genRandomInit(fir::FirOpBuilder &, mlir::Location, mlir::Value repeatable,
mlir::Value imageDistinct);
void genRandomNumber(fir::FirOpBuilder &, mlir::Location, mlir::Value harvest);
diff --git a/flang/include/flang/Runtime/command.h b/flang/include/flang/Runtime/command.h
index e4597c480d65ea..7ab3f6442dcf92 100644
--- a/flang/include/flang/Runtime/command.h
+++ b/flang/include/flang/Runtime/command.h
@@ -15,9 +15,6 @@
#ifdef _WIN32
// On Windows* OS GetCurrentProcessId returns DWORD aka uint32_t
typedef std::uint32_t pid_t;
-// UID and GID don't exist on Windows, these exist to avoid errors.
-typedef std::uint32_t uid_t;
-typedef std::uint32_t gid_t;
#else
#include "sys/types.h" //pid_t
#endif
@@ -32,15 +29,9 @@ extern "C" {
// integer kind.
std::int32_t RTNAME(ArgumentCount)();
-// Calls getgid()
-gid_t RTNAME(GetGID)();
-
// Calls getpid()
pid_t RTNAME(GetPID)();
-// Calls getuid()
-uid_t RTNAME(GetUID)();
-
// 16.9.82 GET_COMMAND
// Try to get the value of the whole command. All of the parameters are
// optional.
diff --git a/flang/include/flang/Runtime/extensions.h b/flang/include/flang/Runtime/extensions.h
index fef651f3b2eedb..6a842bafc155f9 100644
--- a/flang/include/flang/Runtime/extensions.h
+++ b/flang/include/flang/Runtime/extensions.h
@@ -20,6 +20,14 @@
#include <cstddef>
#include <cstdint>
+#ifdef _WIN32
+// UID and GID don't exist on Windows, these exist to avoid errors.
+typedef std::uint32_t uid_t;
+typedef std::uint32_t gid_t;
+#else
+#include "sys/types.h" //pid_t
+#endif
+
extern "C" {
// CALL FLUSH(n) antedates the Fortran 2003 FLUSH statement.
@@ -35,6 +43,12 @@ std::int32_t FORTRAN_PROCEDURE_NAME(iargc)();
void FORTRAN_PROCEDURE_NAME(getarg)(
std::int32_t &n, char *arg, std::int64_t length);
+// Calls getgid()
+gid_t RTNAME(GetGID)();
+
+// Calls getuid()
+uid_t RTNAME(GetUID)();
+
// GNU extension subroutine GETLOG(C).
void FORTRAN_PROCEDURE_NAME(getlog)(char *name, std::int64_t length);
diff --git a/flang/lib/Optimizer/Builder/Runtime/Command.cpp b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
index d035c9156e1e8c..8320d89493b336 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Command.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
@@ -48,14 +48,6 @@ mlir::Value fir::runtime::genGetCommand(fir::FirOpBuilder &builder,
return builder.create<fir::CallOp>(loc, runtimeFunc, args).getResult(0);
}
-mlir::Value fir::runtime::genGetGID(fir::FirOpBuilder &builder,
- mlir::Location loc) {
- auto runtimeFunc =
- fir::runtime::getRuntimeFunc<mkRTKey(GetGID)>(loc, builder);
-
- return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
-}
-
mlir::Value fir::runtime::genGetPID(fir::FirOpBuilder &builder,
mlir::Location loc) {
auto runtimeFunc =
@@ -64,14 +56,6 @@ mlir::Value fir::runtime::genGetPID(fir::FirOpBuilder &builder,
return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
}
-mlir::Value fir::runtime::genGetUID(fir::FirOpBuilder &builder,
- mlir::Location loc) {
- auto runtimeFunc =
- fir::runtime::getRuntimeFunc<mkRTKey(GetUID)>(loc, builder);
-
- return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
-}
-
mlir::Value fir::runtime::genGetCommandArgument(
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value number,
mlir::Value value, mlir::Value length, mlir::Value errmsg) {
diff --git a/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp b/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
index aff3cadc3c300d..6bdc7d8c6bc823 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
@@ -120,6 +120,22 @@ void fir::runtime::genEtime(fir::FirOpBuilder &builder, mlir::Location loc,
builder.create<fir::CallOp>(loc, runtimeFunc, args);
}
+mlir::Value fir::runtime::genGetGID(fir::FirOpBuilder &builder,
+ mlir::Location loc) {
+ auto runtimeFunc =
+ fir::runtime::getRuntimeFunc<mkRTKey(GetGID)>(loc, builder);
+
+ return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
+}
+
+mlir::Value fir::runtime::genGetUID(fir::FirOpBuilder &builder,
+ mlir::Location loc) {
+ auto runtimeFunc =
+ fir::runtime::getRuntimeFunc<mkRTKey(GetUID)>(loc, builder);
+
+ return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
+}
+
void fir::runtime::genRandomInit(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value repeatable,
mlir::Value imageDistinct) {
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 63152a62a5789a..e77a2eca7d3b5e 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -2023,6 +2023,8 @@ bool CheckPPCIntrinsic(const Symbol &generic, const Symbol &specific,
bool CheckWindowsIntrinsic(
const Symbol &intrinsic, evaluate::FoldingContext &foldingContext) {
parser::ContextualMessages &messages{foldingContext.messages()};
+ // TODO: there are other intrinsics that are unsupported on Windows that
+ // should be added here.
if (intrinsic.name() == "getuid") {
messages.Say(
"User IDs do not exist on Windows. This function will always return 1"_warn_en_US);
diff --git a/flang/runtime/command.cpp b/flang/runtime/command.cpp
index 3e0bc396da4da0..a555e26f96a66c 100644
--- a/flang/runtime/command.cpp
+++ b/flang/runtime/command.cpp
@@ -42,26 +42,8 @@ std::int32_t RTNAME(ArgumentCount)() {
return 0;
}
-gid_t RTNAME(GetGID)() {
-#ifdef _WIN32
- // Group IDs don't exist on Windows, return 1 to avoid errors
- return 1;
-#else
- return getgid();
-#endif
-}
-
pid_t RTNAME(GetPID)() { return getpid(); }
-uid_t RTNAME(GetUID)() {
-#ifdef _WIN32
- // User IDs don't exist on Windows, return 1 to avoid errors
- return 1;
-#else
- return getuid();
-#endif
-}
-
// Returns the length of the \p string. Assumes \p string is valid.
static std::int64_t StringLength(const char *string) {
std::size_t length{std::strlen(string)};
diff --git a/flang/runtime/extensions.cpp b/flang/runtime/extensions.cpp
index be3833db88b07a..f2823ca770bc5f 100644
--- a/flang/runtime/extensions.cpp
+++ b/flang/runtime/extensions.cpp
@@ -58,6 +58,24 @@ extern "C" {
namespace Fortran::runtime {
+gid_t RTNAME(GetGID)() {
+#ifdef _WIN32
+ // Group IDs don't exist on Windows, return 1 to avoid errors
+ return 1;
+#else
+ return getgid();
+#endif
+}
+
+uid_t RTNAME(GetUID)() {
+#ifdef _WIN32
+ // User IDs don't exist on Windows, return 1 to avoid errors
+ return 1;
+#else
+ return getuid();
+#endif
+}
+
void GetUsernameEnvVar(const char *envName, char *arg, std::int64_t length) {
Descriptor name{*Descriptor::Create(
1, std::strlen(envName) + 1, const_cast<char *>(envName), 0)};
@@ -66,6 +84,7 @@ void GetUsernameEnvVar(const char *envName, char *arg, std::int64_t length) {
RTNAME(GetEnvVariable)
(name, &value, nullptr, false, nullptr, __FILE__, __LINE__);
}
+
namespace io {
// SUBROUTINE FLUSH(N)
// FLUSH N
>From 3b26e2523df7f8876eac79a15333e3ffd358c014 Mon Sep 17 00:00:00 2001
From: David Truby <david.truby at arm.com>
Date: Thu, 26 Sep 2024 09:35:03 +0100
Subject: [PATCH 3/4] Remove double declaration of gen functions
---
flang/include/flang/Optimizer/Builder/Runtime/Command.h | 3 ---
1 file changed, 3 deletions(-)
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Command.h b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
index 50b655a6bc9e6c..0d60a367d99981 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Command.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
@@ -58,8 +58,5 @@ mlir::Value genGetEnvVariable(fir::FirOpBuilder &, mlir::Location,
mlir::Value genGetCwd(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value c);
-mlir::Value genGetUID(fir::FirOpBuilder &, mlir::Location);
-mlir::Value genGetGID(fir::FirOpBuilder &, mlir::Location);
-
} // namespace fir::runtime
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COMMAND_H
>From 615ab5b63a1d43be55a32a0a107854a84df5145a Mon Sep 17 00:00:00 2001
From: David Truby <david.truby at arm.com>
Date: Thu, 26 Sep 2024 15:04:18 +0100
Subject: [PATCH 4/4] Fix build error moving functions around.
---
.../Optimizer/Builder/Runtime/CommandTest.cpp | 14 --------------
.../Builder/Runtime/IntrinsicsTest.cpp | 17 +++++++++++++++++
flang/unittests/Optimizer/CMakeLists.txt | 1 +
flang/unittests/Runtime/CommandTest.cpp | 10 ----------
4 files changed, 18 insertions(+), 24 deletions(-)
create mode 100644 flang/unittests/Optimizer/Builder/Runtime/IntrinsicsTest.cpp
diff --git a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
index 12f479247a41d8..8bc1e87814a98c 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
@@ -45,23 +45,9 @@ TEST_F(RuntimeCallTest, genGetEnvVariable) {
/*addLocArgs=*/true);
}
-TEST_F(RuntimeCallTest, genGetGID) {
- mlir::Location loc = firBuilder->getUnknownLoc();
- mlir::Value result = fir::runtime::genGetGID(*firBuilder, loc);
- checkCallOp(result.getDefiningOp(), "_FortranAGetGID", /*nbArgs=*/0,
- /*addLocArgs=*/false);
-}
-
TEST_F(RuntimeCallTest, genGetPID) {
mlir::Location loc = firBuilder->getUnknownLoc();
mlir::Value result = fir::runtime::genGetPID(*firBuilder, loc);
checkCallOp(result.getDefiningOp(), "_FortranAGetPID", /*nbArgs=*/0,
/*addLocArgs=*/false);
}
-
-TEST_F(RuntimeCallTest, genGetUID) {
- mlir::Location loc = firBuilder->getUnknownLoc();
- mlir::Value result = fir::runtime::genGetUID(*firBuilder, loc);
- checkCallOp(result.getDefiningOp(), "_FortranAGetUID", /*nbArgs=*/0,
- /*addLocArgs=*/false);
-}
diff --git a/flang/unittests/Optimizer/Builder/Runtime/IntrinsicsTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/IntrinsicsTest.cpp
new file mode 100644
index 00000000000000..1440a5fd01c2b1
--- /dev/null
+++ b/flang/unittests/Optimizer/Builder/Runtime/IntrinsicsTest.cpp
@@ -0,0 +1,17 @@
+#include "flang/Optimizer/Builder/Runtime/Intrinsics.h"
+#include "RuntimeCallTestBase.h"
+#include "gtest/gtest.h"
+
+TEST_F(RuntimeCallTest, genGetGID) {
+ mlir::Location loc = firBuilder->getUnknownLoc();
+ mlir::Value result = fir::runtime::genGetGID(*firBuilder, loc);
+ checkCallOp(result.getDefiningOp(), "_FortranAGetGID", /*nbArgs=*/0,
+ /*addLocArgs=*/false);
+}
+
+TEST_F(RuntimeCallTest, genGetUID) {
+ mlir::Location loc = firBuilder->getUnknownLoc();
+ mlir::Value result = fir::runtime::genGetUID(*firBuilder, loc);
+ checkCallOp(result.getDefiningOp(), "_FortranAGetUID", /*nbArgs=*/0,
+ /*addLocArgs=*/false);
+}
diff --git a/flang/unittests/Optimizer/CMakeLists.txt b/flang/unittests/Optimizer/CMakeLists.txt
index 7299e3ee0529a9..c58fb226a175c9 100644
--- a/flang/unittests/Optimizer/CMakeLists.txt
+++ b/flang/unittests/Optimizer/CMakeLists.txt
@@ -25,6 +25,7 @@ add_flang_unittest(FlangOptimizerTests
Builder/Runtime/CommandTest.cpp
Builder/Runtime/CharacterTest.cpp
Builder/Runtime/DerivedTest.cpp
+ Builder/Runtime/IntrinsicsTest.cpp
Builder/Runtime/NumericTest.cpp
Builder/Runtime/RaggedTest.cpp
Builder/Runtime/ReductionTest.cpp
diff --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index 02e0cd94b5ef5b..b0c43ba01d8f33 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -689,21 +689,11 @@ TEST_F(OnlyValidArguments, GetCommandShortLength) {
CheckDescriptorEqInt<short>(length.get(), 51);
}
-TEST_F(ZeroArguments, GetGID) {
- // gid cannot be negative
- EXPECT_GE(RTNAME(GetGID)(), 0u);
-}
-
TEST_F(ZeroArguments, GetPID) {
// pid should always greater than 0, in both linux and windows
EXPECT_GT(RTNAME(GetPID)(), 0);
}
-TEST_F(ZeroArguments, GetUID) {
- // uid cannot be negative
- EXPECT_GE(RTNAME(GetUID)(), 0u);
-}
-
class EnvironmentVariables : public CommandFixture {
protected:
EnvironmentVariables() : CommandFixture(0, nullptr) {
More information about the flang-commits
mailing list