[flang-commits] [flang] [flang][Runtime] Add SIGNAL intrinisic (PR #79337)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Thu Jan 25 03:16:17 PST 2024
================
@@ -235,3 +237,66 @@ void fir::runtime::genSystemClock(fir::FirOpBuilder &builder,
if (max)
makeCall(getRuntimeFunc<mkRTKey(SystemClockCountMax)>(loc, builder), max);
}
+
+// CALL SIGNAL(NUMBER, HANDLER [, STATUS])
+// The definition of the SIGNAL intrinsic allows HANDLER to be a function
+// pointer or an integer. STATUS can be dynamically optional
+void fir::runtime::genSignal(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value number, mlir::Value handler,
+ mlir::Value status) {
+ assert(mlir::isa<mlir::IntegerType>(number.getType()));
+ if (status)
+ assert(mlir::isa<mlir::IntegerType>(fir::unwrapRefType(status.getType())));
+ mlir::Type int64 = builder.getIntegerType(64);
+ number = builder.create<fir::ConvertOp>(loc, int64, number);
+
+ // we can return like a function or via the status argument
+ auto returnStatus = [&](mlir::Value stat) -> mlir::Value {
+ if (status) {
+ // status might be dynamically optional, so test if it is present
+ mlir::Value isPresent =
+ builder.create<IsPresentOp>(loc, builder.getI1Type(), status);
+ builder.genIfOp(loc, /*results=*/{}, isPresent, /*withElseRegion=*/false)
+ .genThen([&]() {
+ stat = builder.create<fir::ConvertOp>(
+ loc, fir::unwrapRefType(status.getType()), stat);
+ builder.create<fir::StoreOp>(loc, stat, status);
+ })
+ .end();
+ }
+ return {};
+ };
+
+ mlir::Type handlerUnwrappedTy = fir::unwrapRefType(handler.getType());
+ if (mlir::isa_and_nonnull<mlir::IntegerType>(handlerUnwrappedTy)) {
+#if _WIN32
+ // The windows documentation doesn't mention any support for passing
+ // SIG_DFL or SIG_IGN as integer arguments, so just return an error.
+
+ // reinterpret cast: the GNU extension is defined with STATUS as an integer
+ // but on Windows SIG_ERR is a void *
+ const std::int64_t sigErrVal =
+ static_cast<std::int64_t>(reinterpret_cast<std::uintptr_t>(SIG_ERR));
+ mlir::Value sigErr = builder.createIntegerConstant(loc, int64, sigErrVal);
+ returnStatus(sigErr);
+ errno = EINVAL;
----------------
tblah wrote:
Ahh you are right. Oops!
I will remove the special case for windows. `SIG_IGN` and `SIG_DFL` are in C89 so the Windows implementation of signal may still support them, and if they aren't, presumably the programmer would realize while trying to look up/include the correct integer constants to use.
https://github.com/llvm/llvm-project/pull/79337
More information about the flang-commits
mailing list