diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp --- a/flang/lib/Lower/Runtime.cpp +++ b/flang/lib/Lower/Runtime.cpp @@ -42,8 +42,27 @@ mlir::FuncOp callee; mlir::FunctionType calleeType; // First operand is stop code (zero if absent) - if (std::get>(stmt.t)) { - TODO(loc, "STOP first operand not lowered yet"); + if (const auto &code = + std::get>(stmt.t)) { + auto expr = converter.genExprValue(*Fortran::semantics::GetExpr(*code)); + LLVM_DEBUG(llvm::dbgs() << "stop expression: "; expr.dump(); + llvm::dbgs() << '\n'); + expr.match( + [&](const fir::CharBoxValue &x) { + TODO(loc, "STOP CharBoxValue first operand not lowered yet"); + }, + [&](fir::UnboxedValue x) { + callee = fir::runtime::getRuntimeFunc( + loc, builder); + calleeType = callee.getType(); + mlir::Value cast = + builder.createConvert(loc, calleeType.getInput(0), x); + operands.push_back(cast); + }, + [&](auto) { + mlir::emitError(loc, "unhandled expression in STOP"); + std::exit(1); + }); } else { callee = fir::runtime::getRuntimeFunc(loc, builder); calleeType = callee.getType(); diff --git a/flang/test/Lower/stop-statement.f90 b/flang/test/Lower/stop-statement.f90 --- a/flang/test/Lower/stop-statement.f90 +++ b/flang/test/Lower/stop-statement.f90 @@ -19,3 +19,12 @@ ! CHECK: fir.call @_Fortran{{.*}}StopStatement(%[[c0]], %[[true]], %[[false]]) ! CHECK-NEXT: fir.unreachable end subroutine + +! CHECK-LABEL stop_code +subroutine stop_code() + stop 42 + ! CHECK-DAG: %[[c42:.*]] = arith.constant 42 : i32 + ! CHECK-DAG: %[[false:.*]] = arith.constant false + ! CHECK: fir.call @_Fortran{{.*}}StopStatement(%[[c42]], %[[false]], %[[false]]) + ! CHECK-NEXT: fir.unreachable +end subroutine