Skip to content

Commit 054eadc

Browse files
DavidTrubyyiwu0b11
andauthored
[flang] Implement GETUID and GETGID intrinsics (#108017)
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 <[email protected]> --------- Co-authored-by: Yi Wu <[email protected]>
1 parent ec08c11 commit 054eadc

File tree

17 files changed

+138
-2
lines changed

17 files changed

+138
-2
lines changed

flang/docs/Intrinsics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ This phase currently supports all the intrinsic procedures listed above but the
765765
| Coarray intrinsic functions | COSHAPE |
766766
| Object characteristic inquiry functions | ALLOCATED, ASSOCIATED, EXTENDS_TYPE_OF, IS_CONTIGUOUS, PRESENT, RANK, SAME_TYPE, STORAGE_SIZE |
767767
| Type inquiry intrinsic functions | BIT_SIZE, DIGITS, EPSILON, HUGE, KIND, MAXEXPONENT, MINEXPONENT, NEW_LINE, PRECISION, RADIX, RANGE, TINY|
768-
| 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 |
768+
| 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 |
769769
| 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 |
770770
| Atomic intrinsic subroutines | ATOMIC_ADD |
771771
| Collective intrinsic subroutines | CO_REDUCE |

flang/include/flang/Evaluate/target.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ class TargetCharacteristics {
102102
bool isPPC() const { return isPPC_; }
103103
void set_isPPC(bool isPPC = false);
104104

105+
bool isOSWindows() const { return isOSWindows_; }
106+
void set_isOSWindows(bool isOSWindows = false) {
107+
isOSWindows_ = isOSWindows;
108+
};
109+
105110
IeeeFeatures &ieeeFeatures() { return ieeeFeatures_; }
106111
const IeeeFeatures &ieeeFeatures() const { return ieeeFeatures_; }
107112

@@ -111,6 +116,7 @@ class TargetCharacteristics {
111116
std::uint8_t align_[common::TypeCategory_enumSize][maxKind]{};
112117
bool isBigEndian_{false};
113118
bool isPPC_{false};
119+
bool isOSWindows_{false};
114120
bool areSubnormalsFlushedToZero_{false};
115121
Rounding roundingMode_{defaultRounding};
116122
std::size_t procedurePointerByteSize_{8};

flang/include/flang/Optimizer/Builder/IntrinsicCall.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ struct IntrinsicLibrary {
256256
llvm::ArrayRef<mlir::Value> args);
257257
void genGetCommandArgument(mlir::ArrayRef<fir::ExtendedValue> args);
258258
void genGetEnvironmentVariable(llvm::ArrayRef<fir::ExtendedValue>);
259+
mlir::Value genGetGID(mlir::Type resultType,
260+
llvm::ArrayRef<mlir::Value> args);
261+
mlir::Value genGetUID(mlir::Type resultType,
262+
llvm::ArrayRef<mlir::Value> args);
259263
fir::ExtendedValue genIall(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
260264
mlir::Value genIand(mlir::Type, llvm::ArrayRef<mlir::Value>);
261265
fir::ExtendedValue genIany(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);

flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ void genDateAndTime(fir::FirOpBuilder &, mlir::Location,
4747
void genEtime(fir::FirOpBuilder &builder, mlir::Location loc,
4848
mlir::Value values, mlir::Value time);
4949

50+
mlir::Value genGetUID(fir::FirOpBuilder &, mlir::Location);
51+
mlir::Value genGetGID(fir::FirOpBuilder &, mlir::Location);
52+
5053
void genRandomInit(fir::FirOpBuilder &, mlir::Location, mlir::Value repeatable,
5154
mlir::Value imageDistinct);
5255
void genRandomNumber(fir::FirOpBuilder &, mlir::Location, mlir::Value harvest);

flang/include/flang/Runtime/extensions.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
#include <cstddef>
2121
#include <cstdint>
2222

23+
#ifdef _WIN32
24+
// UID and GID don't exist on Windows, these exist to avoid errors.
25+
typedef std::uint32_t uid_t;
26+
typedef std::uint32_t gid_t;
27+
#else
28+
#include "sys/types.h" //pid_t
29+
#endif
30+
2331
extern "C" {
2432

2533
// CALL FLUSH(n) antedates the Fortran 2003 FLUSH statement.
@@ -35,6 +43,12 @@ std::int32_t FORTRAN_PROCEDURE_NAME(iargc)();
3543
void FORTRAN_PROCEDURE_NAME(getarg)(
3644
std::int32_t &n, char *arg, std::int64_t length);
3745

46+
// Calls getgid()
47+
gid_t RTNAME(GetGID)();
48+
49+
// Calls getuid()
50+
uid_t RTNAME(GetUID)();
51+
3852
// GNU extension subroutine GETLOG(C).
3953
void FORTRAN_PROCEDURE_NAME(getlog)(char *name, std::int64_t length);
4054

flang/include/flang/Tools/TargetSetup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ namespace Fortran::tools {
5959
if (targetTriple.isPPC())
6060
targetCharacteristics.set_isPPC(true);
6161

62+
if (targetTriple.isOSWindows())
63+
targetCharacteristics.set_isOSWindows(true);
64+
6265
// TODO: use target machine data layout to set-up the target characteristics
6366
// type size and alignment info.
6467
}

flang/lib/Evaluate/intrinsics.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,9 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
523523
{{"c", DefaultChar, Rank::scalar, Optionality::required,
524524
common::Intent::Out}},
525525
TypePattern{IntType, KindCode::greaterOrEqualToKind, 4}},
526+
{"getgid", {}, DefaultInt},
526527
{"getpid", {}, DefaultInt},
528+
{"getuid", {}, DefaultInt},
527529
{"huge",
528530
{{"x", SameIntOrReal, Rank::anyOrAssumedRank, Optionality::required,
529531
common::Intent::In, {ArgFlag::canBeMoldNull}}},

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,9 @@ static constexpr IntrinsicHandler handlers[]{
293293
&I::genGetCwd,
294294
{{{"c", asBox}, {"status", asAddr, handleDynamicOptional}}},
295295
/*isElemental=*/false},
296+
{"getgid", &I::genGetGID},
296297
{"getpid", &I::genGetPID},
298+
{"getuid", &I::genGetUID},
297299
{"iachar", &I::genIchar},
298300
{"iall",
299301
&I::genIall,
@@ -3650,6 +3652,14 @@ void IntrinsicLibrary::genGetCommand(llvm::ArrayRef<fir::ExtendedValue> args) {
36503652
}
36513653
}
36523654

3655+
// GETGID
3656+
mlir::Value IntrinsicLibrary::genGetGID(mlir::Type resultType,
3657+
llvm::ArrayRef<mlir::Value> args) {
3658+
assert(args.size() == 0 && "getgid takes no input");
3659+
return builder.createConvert(loc, resultType,
3660+
fir::runtime::genGetGID(builder, loc));
3661+
}
3662+
36533663
// GETPID
36543664
mlir::Value IntrinsicLibrary::genGetPID(mlir::Type resultType,
36553665
llvm::ArrayRef<mlir::Value> args) {
@@ -3658,6 +3668,14 @@ mlir::Value IntrinsicLibrary::genGetPID(mlir::Type resultType,
36583668
fir::runtime::genGetPID(builder, loc));
36593669
}
36603670

3671+
// GETUID
3672+
mlir::Value IntrinsicLibrary::genGetUID(mlir::Type resultType,
3673+
llvm::ArrayRef<mlir::Value> args) {
3674+
assert(args.size() == 0 && "getgid takes no input");
3675+
return builder.createConvert(loc, resultType,
3676+
fir::runtime::genGetUID(builder, loc));
3677+
}
3678+
36613679
// GET_COMMAND_ARGUMENT
36623680
void IntrinsicLibrary::genGetCommandArgument(
36633681
llvm::ArrayRef<fir::ExtendedValue> args) {

flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,22 @@ void fir::runtime::genEtime(fir::FirOpBuilder &builder, mlir::Location loc,
120120
builder.create<fir::CallOp>(loc, runtimeFunc, args);
121121
}
122122

123+
mlir::Value fir::runtime::genGetGID(fir::FirOpBuilder &builder,
124+
mlir::Location loc) {
125+
auto runtimeFunc =
126+
fir::runtime::getRuntimeFunc<mkRTKey(GetGID)>(loc, builder);
127+
128+
return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
129+
}
130+
131+
mlir::Value fir::runtime::genGetUID(fir::FirOpBuilder &builder,
132+
mlir::Location loc) {
133+
auto runtimeFunc =
134+
fir::runtime::getRuntimeFunc<mkRTKey(GetUID)>(loc, builder);
135+
136+
return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
137+
}
138+
123139
void fir::runtime::genRandomInit(fir::FirOpBuilder &builder, mlir::Location loc,
124140
mlir::Value repeatable,
125141
mlir::Value imageDistinct) {

flang/lib/Semantics/check-call.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,6 +2028,22 @@ bool CheckPPCIntrinsic(const Symbol &generic, const Symbol &specific,
20282028
return false;
20292029
}
20302030

2031+
bool CheckWindowsIntrinsic(
2032+
const Symbol &intrinsic, evaluate::FoldingContext &foldingContext) {
2033+
parser::ContextualMessages &messages{foldingContext.messages()};
2034+
// TODO: there are other intrinsics that are unsupported on Windows that
2035+
// should be added here.
2036+
if (intrinsic.name() == "getuid") {
2037+
messages.Say(
2038+
"User IDs do not exist on Windows. This function will always return 1"_warn_en_US);
2039+
}
2040+
if (intrinsic.name() == "getgid") {
2041+
messages.Say(
2042+
"Group IDs do not exist on Windows. This function will always return 1"_warn_en_US);
2043+
}
2044+
return true;
2045+
}
2046+
20312047
bool CheckArguments(const characteristics::Procedure &proc,
20322048
evaluate::ActualArguments &actuals, SemanticsContext &context,
20332049
const Scope &scope, bool treatingExternalAsImplicit,

0 commit comments

Comments
 (0)