[flang-commits] [flang] [flang][Runtime] Add SIGNAL intrinisic (PR #79337)
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Wed Jan 24 13:29:22 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;
----------------
vzakhari wrote:
Hmm, but `errno` is set here during the compilation not during the program execution. Am I missing something?
https://github.com/llvm/llvm-project/pull/79337
More information about the flang-commits
mailing list