From 1ba36147a8db08211ee1e08ef61af09aad489deb Mon Sep 17 00:00:00 2001 From: Acture Date: Mon, 30 Mar 2026 17:07:37 +0800 Subject: [PATCH] flang: package standalone flang with LLVM 20+ driver fixes Wire flang into llvmPackages as a first-class Fortran compiler. flang is built standalone on top of the LLVM/clang package set rather than bundled into the llvm derivation, with passthru metadata (`langFortran`, `isFlang`, `isClang`, `hardeningUnsupportedFlags`) so cc-wrapper and downstream tooling can detect and adapt to it. Driver compatibility patches backported from upstream are applied selectively per LLVM version: * `use-xflang-in-diagnostics` is applied to LLVM 20 and newer; it teaches the driver to suggest `-Xflang` instead of `-Xclang` in error messages for options only available to `flang -fc1`. * `warn-on-fbuiltin-and-fno-builtin` and `accept-and-ignore-some-gfortran-optimization-flags` are applied to LLVM 20 and 21 only. LLVM 22 has equivalent behaviour merged upstream (`warn_drv_invalid_argument_for_flang` and `clang_ignored_gcc_optimization_f_Group` handling in clang/lib/Driver/ToolChains/Flang.cpp), so the patches are skipped there. Patches live under pkgs/development/compilers/llvm/21/flang/ and are shared across versions via patches.nix. They are applied to a private libclang variant rather than the flang source tree because standalone flang resolves driver/option definitions through the installed libclang package. Two focused passthru tests are added: * `compile-smoke` exercises basic compilation and `@response-file` handling. * `driver-flags` covers wrapper flag isolation (`NIX_CFLAGS_COMPILE` must not leak into flang; `NIX_FFLAGS_COMPILE` must reach it), the backported driver diagnostics, and regression coverage for previously hard-erroring flags. Build on the earlier standalone flang work by @picostove. Co-authored-by: stove Co-authored-by: acture Co-authored-by: Alyssa Ross --- ...ore-some-gfortran-optimization-flags.patch | 49 ++++++++ .../21/flang/use-xflang-in-diagnostics.patch | 40 +++++++ .../warn-on-fbuiltin-and-fno-builtin.patch | 74 ++++++++++++ .../compilers/llvm/common/default.nix | 107 ++++++++++++++---- .../compilers/llvm/common/flang/default.nix | 50 +++++--- .../llvm/common/flang/dummy_target_19+.patch | 6 +- .../compilers/llvm/common/flang/tests.nix | 92 +++++++++++++++ .../compilers/llvm/common/patches.nix | 20 ++++ 8 files changed, 398 insertions(+), 40 deletions(-) create mode 100644 pkgs/development/compilers/llvm/21/flang/accept-and-ignore-some-gfortran-optimization-flags.patch create mode 100644 pkgs/development/compilers/llvm/21/flang/use-xflang-in-diagnostics.patch create mode 100644 pkgs/development/compilers/llvm/21/flang/warn-on-fbuiltin-and-fno-builtin.patch create mode 100644 pkgs/development/compilers/llvm/common/flang/tests.nix diff --git a/pkgs/development/compilers/llvm/21/flang/accept-and-ignore-some-gfortran-optimization-flags.patch b/pkgs/development/compilers/llvm/21/flang/accept-and-ignore-some-gfortran-optimization-flags.patch new file mode 100644 index 000000000000..912be7169621 --- /dev/null +++ b/pkgs/development/compilers/llvm/21/flang/accept-and-ignore-some-gfortran-optimization-flags.patch @@ -0,0 +1,49 @@ +From da7174958be43d69b2ed6b581c8ac8a382b59180 Mon Sep 17 00:00:00 2001 +From: Tarun Prabhu +Date: Tue, 28 Oct 2025 19:35:27 -0600 +Subject: [PATCH] [flang][Driver] Accept (and ignore) some gfortran-specific + options + +Enable the clang_ignored_gcc_optimization_f_group in flang. These options are +accepted by clang, but ignored after emitting a warning message. flang's +behavior now mirrors clang. + +Fixes #158436 +--- + clang/include/clang/Driver/Options.td | 3 ++- + clang/lib/Driver/ToolChains/Flang.cpp | 8 ++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td +index ef1c8758705f4..cac122d296624 100644 +--- a/include/clang/Driver/Options.td ++++ b/include/clang/Driver/Options.td +@@ -316,7 +316,8 @@ def mno_mpx : Flag<["-"], "mno-mpx">, Group; + + // Group that ignores all gcc optimizations that won't be implemented + def clang_ignored_gcc_optimization_f_Group : OptionGroup< +- "">, Group, Flags<[Ignored]>; ++ "">, ++ Group, Flags<[Ignored]>, Visibility<[ClangOption, FlangOption]>; + + class DiagnosticOpts + : KeyPathAndMacro<"DiagnosticOpts->", base, "DIAG_"> {} +diff --git a/lib/Driver/ToolChains/Flang.cpp b/lib/Driver/ToolChains/Flang.cpp +index 88bce181d40d2..2f5e93d139858 100644 +--- a/lib/Driver/ToolChains/Flang.cpp ++++ b/lib/Driver/ToolChains/Flang.cpp +@@ -858,6 +858,14 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, + if (const Arg *A = Args.getLastArg(Opt)) + D.Diag(diag::warn_drv_invalid_argument_for_flang) << A->getSpelling(); + ++ // Warn about options that are ignored by flang. These are options that are ++ // accepted by gfortran, but have no equivalent in flang. ++ for (const Arg *A : ++ Args.filtered(options::OPT_clang_ignored_gcc_optimization_f_Group)) { ++ D.Diag(diag::warn_ignored_gcc_optimization) << A->getAsString(Args); ++ A->claim(); ++ } ++ + const InputInfo &Input = Inputs[0]; + types::ID InputType = Input.getType(); + diff --git a/pkgs/development/compilers/llvm/21/flang/use-xflang-in-diagnostics.patch b/pkgs/development/compilers/llvm/21/flang/use-xflang-in-diagnostics.patch new file mode 100644 index 000000000000..29af46eba798 --- /dev/null +++ b/pkgs/development/compilers/llvm/21/flang/use-xflang-in-diagnostics.patch @@ -0,0 +1,40 @@ +From 9ab9d33171ee35c948967a2a2d714b8059887607 Mon Sep 17 00:00:00 2001 +From: Tarun Prabhu +Date: Wed, 29 Oct 2025 09:13:17 -0600 +Subject: [PATCH] [flang][driver] Use -Xflang in diagnostics + +When an option that is only available in `flang -fc1` is provided to +`flang`, emit a diagnostic with a suggestion containing "did you mean +-Xflang '-foo'". + +Partially addresses #163550. +--- + clang/lib/Driver/Driver.cpp | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp +index 40ea513e85427..71c52807091ba 100644 +--- a/lib/Driver/Driver.cpp ++++ b/lib/Driver/Driver.cpp +@@ -365,9 +365,18 @@ + auto ArgString = A->getAsString(Args); + std::string Nearest; + if (getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) { +- if (!IsCLMode() && +- getOpts().findExact(ArgString, Nearest, +- llvm::opt::Visibility(options::CC1Option))) { ++ if (IsFlangMode()) { ++ if (getOpts().findExact(ArgString, Nearest, ++ llvm::opt::Visibility(options::FC1Option))) { ++ DiagID = diag::err_drv_unknown_argument_with_suggestion; ++ Diags.Report(DiagID) << ArgString << "-Xflang " + Nearest; ++ } else { ++ DiagID = diag::err_drv_unknown_argument; ++ Diags.Report(DiagID) << ArgString; ++ } ++ } else if (!IsCLMode() && getOpts().findExact(ArgString, Nearest, ++ llvm::opt::Visibility( ++ options::CC1Option))) { + DiagID = diag::err_drv_unknown_argument_with_suggestion; + Diags.Report(DiagID) << ArgString << "-Xclang " + Nearest; + } else { diff --git a/pkgs/development/compilers/llvm/21/flang/warn-on-fbuiltin-and-fno-builtin.patch b/pkgs/development/compilers/llvm/21/flang/warn-on-fbuiltin-and-fno-builtin.patch new file mode 100644 index 000000000000..ee2cb99b57a5 --- /dev/null +++ b/pkgs/development/compilers/llvm/21/flang/warn-on-fbuiltin-and-fno-builtin.patch @@ -0,0 +1,74 @@ +From 263377a175709c2d11f3ff63c2d2d2843afb91ea Mon Sep 17 00:00:00 2001 +From: Tarun Prabhu +Date: Thu, 23 Oct 2025 13:24:20 -0600 +Subject: [PATCH] [flang][Driver] Warn on -fbuiltin and -fno-builtin + +The options -fbuiltin and -fno-builtin are not valid for Fortran. However, +they are accepted by gfortran which emits a warning message but continues to +compile the code. Both -fbuiltin and -fno-builtin have been enabled for flang. +Specifying either will result in a warning message being shown but no other +effects. Compilation will proceed normally after these warnings are shown. This +brings flang's behavior in line with gfortran for these options. + +Fixes #164766 +--- + clang/include/clang/Basic/DiagnosticDriverKinds.td | 3 +++ + clang/include/clang/Driver/Options.td | 4 ++-- + clang/lib/Driver/ToolChains/Flang.cpp | 7 +++++++ + 3 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td +index 0581bf353d936..83980e3ac35b7 100644 +--- a/include/clang/Basic/DiagnosticDriverKinds.td ++++ b/include/clang/Basic/DiagnosticDriverKinds.td +@@ -131,6 +131,9 @@ def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning< + def warn_drv_unsupported_option_for_target : Warning< + "ignoring '%0' option as it is not currently supported for target '%1'">, + InGroup; ++def warn_drv_invalid_argument_for_flang : Warning< ++ "'%0' is not valid for Fortran">, ++ InGroup; + def warn_drv_unsupported_option_for_flang : Warning< + "the argument '%0' is not supported for option '%1'. Mapping to '%1%2'">, + InGroup; +diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td +index ef1c8758705f4..bca8b26bc3d30 100644 +--- a/include/clang/Driver/Options.td ++++ b/include/clang/Driver/Options.td +@@ -1940,7 +1940,7 @@ defm borland_extensions : BoolFOption<"borland-extensions", + "Accept non-standard constructs supported by the Borland compiler">, + NegFlag>; + def fbuiltin : Flag<["-"], "fbuiltin">, Group, +- Visibility<[ClangOption, CLOption, DXCOption]>; ++ Visibility<[ClangOption, CLOption, DXCOption, FlangOption, FC1Option]>; + def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group, + Flags<[]>, HelpText<"Load the clang builtins module map file.">; + defm caret_diagnostics : BoolFOption<"caret-diagnostics", +@@ -3493,7 +3493,7 @@ def fno_assume_sane_operator_new : Flag<["-"], "fno-assume-sane-operator-new">, + HelpText<"Don't assume that C++'s global operator new can't alias any pointer">, + Visibility<[ClangOption, CC1Option]>, + MarshallingInfoNegativeFlag>; + def fno_builtin : Flag<["-"], "fno-builtin">, Group, +- Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, ++ Visibility<[ClangOption, CC1Option, CLOption, DXCOption, FlangOption, FC1Option]>, + HelpText<"Disable implicit builtin knowledge of functions">; + def fno_builtin_ : Joined<["-"], "fno-builtin-">, Group, + Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, +diff --git a/lib/Driver/ToolChains/Flang.cpp b/lib/Driver/ToolChains/Flang.cpp +index a56fa41c49d34..88bce181d40d2 100644 +--- a/lib/Driver/ToolChains/Flang.cpp ++++ b/lib/Driver/ToolChains/Flang.cpp +@@ -851,6 +851,13 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, + assert(false && "Unexpected action class for Flang tool."); + } + ++ // We support some options that are invalid for Fortran and have no effect. ++ // These are solely for compatibility with other compilers. Emit a warning if ++ // any such options are provided, then proceed normally. ++ for (options::ID Opt : {options::OPT_fbuiltin, options::OPT_fno_builtin}) ++ if (const Arg *A = Args.getLastArg(Opt)) ++ D.Diag(diag::warn_drv_invalid_argument_for_flang) << A->getSpelling(); ++ + const InputInfo &Input = Inputs[0]; + types::ID InputType = Input.getType(); + diff --git a/pkgs/development/compilers/llvm/common/default.nix b/pkgs/development/compilers/llvm/common/default.nix index 2a88fecc0b6e..54f579695a12 100644 --- a/pkgs/development/compilers/llvm/common/default.nix +++ b/pkgs/development/compilers/llvm/common/default.nix @@ -476,28 +476,93 @@ makeScopeWithSplicing' { // lib.optionalAttrs (lib.versionAtLeast metadata.release_version "19") { bolt = callPackage ./bolt { }; } - // lib.optionalAttrs (lib.versionAtLeast metadata.release_version "20") { - flang = callPackage ./flang { }; + // lib.optionalAttrs (lib.versionAtLeast metadata.release_version "20") ( + let + # Standalone flang still resolves driver/option definitions via the + # installed libclang package, so keep flang-specific driver backports + # in a private libclang variant instead of patching the flang source + # tree. The `-Xflang` diagnostic improvement applies to every + # supported standalone-flang version (20+); the other two backports + # are only needed up to LLVM 21 because upstream merged equivalent + # behaviour into LLVM 22. + flangDriverPatches = + lib.optionals (lib.versionAtLeast metadata.release_version "20") [ + (metadata.getVersionFile "flang/use-xflang-in-diagnostics.patch") + ] + ++ + lib.optionals + (lib.versionAtLeast metadata.release_version "20" && lib.versionOlder metadata.release_version "22") + [ + (metadata.getVersionFile "flang/warn-on-fbuiltin-and-fno-builtin.patch") + (metadata.getVersionFile "flang/accept-and-ignore-some-gfortran-optimization-flags.patch") + ]; + flangLibclang = + if flangDriverPatches == [ ] then + self.libclang + else + self.libclang.override { + extraPatches = flangDriverPatches; + }; + flangUnwrapped = callPackage ./flang { + libclang = flangLibclang; + }; + flangRt = callPackage ./flang-rt { + buildFlang = buildLlvmPackages.flang-unwrapped; + }; + in + { + flang-unwrapped = flangUnwrapped; + flang-rt = flangRt; + flang = + let + wrapped = wrapCCWith rec { + cc = flangUnwrapped; + bintools = bintools'; + extraPackages = [ targetLlvmPackages.flang-rt ]; + extraBuildCommands = mkExtraBuildCommands0 cc + '' + # triplet however is not used in darwin + PLATFORM_DIR="${if stdenv.targetPlatform.isDarwin then "darwin" else stdenv.targetPlatform.config}" + RT_LIB_PATH="${targetLlvmPackages.flang-rt}/lib/clang/${clangVersion}/lib/$PLATFORM_DIR" + if [ -d "$RT_LIB_PATH" ]; then + ln -s "$RT_LIB_PATH" "$rsrc"/lib + echo "-L$rsrc/lib" >> $out/nix-support/cc-ldflags + else + ln -s "${targetLlvmPackages.flang-rt}/lib" "$rsrc"/lib + echo "-L$rsrc/lib" >> $out/nix-support/cc-ldflags + fi + ''; + }; + tests = callPackage ./flang/tests.nix { + flang = wrapped; + }; + in + wrapped + // { + passthru = (wrapped.passthru or { }) // { + inherit tests; + }; + }; - libc-overlay = callPackage ./libc { - isFullBuild = false; - # Use clang due to "gnu::naked" not working on aarch64. - # Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882 - stdenv = overrideCC stdenv buildLlvmPackages.clang; - }; + libc-overlay = callPackage ./libc { + isFullBuild = false; + # Use clang due to "gnu::naked" not working on aarch64. + # Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882 + stdenv = overrideCC stdenv buildLlvmPackages.clang; + }; - libc-full = callPackage ./libc { - isFullBuild = true; - # Use clang due to "gnu::naked" not working on aarch64. - # Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882 - stdenv = overrideCC stdenv buildLlvmPackages.clangNoLibcNoRt; - # FIXME: This should almost certainly be `stdenv.hostPlatform`. - cmake = if stdenv.targetPlatform.libc == "llvm" then cmakeMinimal else cmake; - python3 = if stdenv.targetPlatform.libc == "llvm" then python3Minimal else python3; - }; + libc-full = callPackage ./libc { + isFullBuild = true; + # Use clang due to "gnu::naked" not working on aarch64. + # Issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77882 + stdenv = overrideCC stdenv buildLlvmPackages.clangNoLibcNoRt; + # FIXME: This should almost certainly be `stdenv.hostPlatform`. + cmake = if stdenv.targetPlatform.libc == "llvm" then cmakeMinimal else cmake; + python3 = if stdenv.targetPlatform.libc == "llvm" then python3Minimal else python3; + }; - libc = - # FIXME: This should almost certainly be `stdenv.hostPlatform`. - if stdenv.targetPlatform.libc == "llvm" then self.libc-full else self.libc-overlay; - }; + libc = + # FIXME: This should almost certainly be `stdenv.hostPlatform`. + if stdenv.targetPlatform.libc == "llvm" then self.libc-full else self.libc-overlay; + } + ); } diff --git a/pkgs/development/compilers/llvm/common/flang/default.nix b/pkgs/development/compilers/llvm/common/flang/default.nix index 335633d7d19c..0cd94ab4b4b9 100644 --- a/pkgs/development/compilers/llvm/common/flang/default.nix +++ b/pkgs/development/compilers/llvm/common/flang/default.nix @@ -23,21 +23,27 @@ stdenv.mkDerivation (finalAttrs: { pname = "flang"; inherit version; - src = runCommand "flang-src-${version}" { inherit (monorepoSrc) passthru; } '' - mkdir -p "$out" - cp -r ${monorepoSrc}/${finalAttrs.pname} "$out" - cp -r ${monorepoSrc}/cmake "$out" - cp -r ${monorepoSrc}/llvm "$out" - cp -r ${monorepoSrc}/clang "$out" - cp -r ${monorepoSrc}/mlir "$out" - cp -r ${monorepoSrc}/third-party "$out" - chmod -R +w $out/llvm - ''; + src = + runCommand "${finalAttrs.pname}-src-${finalAttrs.version}" + { + inherit (monorepoSrc) passthru; + } + '' + mkdir -p "$out" + cp -r ${monorepoSrc}/${finalAttrs.pname} "$out" + cp -r ${monorepoSrc}/cmake "$out" + cp -r ${monorepoSrc}/llvm "$out" + cp -r ${monorepoSrc}/clang "$out" + cp -r ${monorepoSrc}/mlir "$out" + cp -r ${monorepoSrc}/third-party "$out" + cp -r ${monorepoSrc}/flang-rt "$out" + chmod -R +w $out/llvm + ''; patches = [ ./dummy_target_19+.patch ]; - patchFlags = [ "-p2" ]; + patchFlags = [ "-p1" ]; sourceRoot = "${finalAttrs.src.name}/flang"; @@ -62,24 +68,36 @@ stdenv.mkDerivation (finalAttrs: { ls -l ${mlir.dev}/lib/cmake/mlir/MLIRConfig.cmake ''; cmakeFlags = [ - (lib.cmakeBool "CMAKE_VERBOSE_MAKEFILE" true) (lib.cmakeFeature "LLVM_DIR" "${libllvm.dev}/lib/cmake/llvm") - # TODO: Needs patches and the `lit` package like other LLVM builds? (lib.cmakeFeature "LLVM_TOOLS_BINARY_DIR" "${buildLlvmPackages.tblgen}/bin/") - (lib.cmakeFeature "LLVM_EXTERNAL_LIT" "${buildLlvmPackages.tblgen}/bin/llvm-lit") (lib.cmakeFeature "CLANG_DIR" "${libclang.dev}/lib/cmake/clang") (lib.cmakeFeature "MLIR_DIR" "${mlir.dev}/lib/cmake/mlir") (lib.cmakeFeature "MLIR_TABLEGEN_EXE" "${buildLlvmPackages.tblgen}/bin/mlir-tblgen") (lib.cmakeFeature "MLIR_TABLEGEN_TARGET" "MLIR-TBLGen") - (lib.cmakeBool "LLVM_BUILD_EXAMPLES" false) + (lib.cmakeBool "MLIR_LINK_MLIR_DYLIB" (!stdenv.hostPlatform.isStatic)) + (lib.cmakeFeature "LLVM_LIT_ARGS" "-v") (lib.cmakeBool "LLVM_ENABLE_PLUGINS" false) (lib.cmakeBool "FLANG_STANDALONE_BUILD" true) (lib.cmakeBool "LLVM_INCLUDE_EXAMPLES" false) (lib.cmakeBool "FLANG_INCLUDE_TESTS" false) - ] ++ devExtraCmakeFlags; + passthru = { + # Used by cc-wrapper to determine whether or not the default setup hook is enabled. + langC = false; + langCC = false; + langFortran = true; + isClang = true; + isFlang = true; + + hardeningUnsupportedFlags = [ + "zerocallusedregs" + "stackprotector" + "stackclashprotection" + ]; + }; + postUnpack = '' chmod -R u+w -- $sourceRoot/.. ''; diff --git a/pkgs/development/compilers/llvm/common/flang/dummy_target_19+.patch b/pkgs/development/compilers/llvm/common/flang/dummy_target_19+.patch index ab09ef650416..a6f295ef50b3 100644 --- a/pkgs/development/compilers/llvm/common/flang/dummy_target_19+.patch +++ b/pkgs/development/compilers/llvm/common/flang/dummy_target_19+.patch @@ -1,7 +1,7 @@ -diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt +diff --git a/CMakeLists.txt b/CMakeLists.txt index 070c39eb6e9a..168c97524943 100644 ---- a/flang/CMakeLists.txt -+++ b/flang/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt @@ -1,6 +1,22 @@ cmake_minimum_required(VERSION 3.20.0) set(LLVM_SUBPROJECT_TITLE "Flang") diff --git a/pkgs/development/compilers/llvm/common/flang/tests.nix b/pkgs/development/compilers/llvm/common/flang/tests.nix new file mode 100644 index 000000000000..4c195b9b27ff --- /dev/null +++ b/pkgs/development/compilers/llvm/common/flang/tests.nix @@ -0,0 +1,92 @@ +{ + runCommand, + flang, +}: +let + flangExe = "${flang}/bin/flang"; + writeHello = '' + cat > hello.f90 <<'EOF' + program hello + end program hello + EOF + ''; +in +{ + compile-smoke = runCommand "flang-compile-smoke" { } '' + set -euo pipefail + + ${writeHello} + + ${flangExe} -c hello.f90 -o compile.o + [ -f compile.o ] + + cat > args.rsp <<'EOF' + -c + hello.f90 + -o + response.o + EOF + + ${flangExe} @args.rsp + [ -f response.o ] + + touch $out + ''; + + driver-flags = runCommand "flang-driver-flags" { } '' + set -euo pipefail + + ${writeHello} + + ${flangExe} -### -c hello.f90 > no-seed.log 2>&1 + if grep -F -- "-frandom-seed=" no-seed.log; then + echo "wrapper unexpectedly injected -frandom-seed" >&2 + exit 1 + fi + + # Confirm that user-supplied NIX_CFLAGS_COMPILE does not leak into the + # Fortran wrapper invocation: the wrapper must source flags from + # NIX_FFLAGS_COMPILE only, so a marker placed in NIX_CFLAGS_COMPILE + # must not appear in the resulting flang command line. + NIX_CFLAGS_COMPILE="-Icflags-leak-marker-include" \ + ${flangExe} -### -c hello.f90 > cflags-isolation.log 2>&1 + if grep -F -- "cflags-leak-marker-include" cflags-isolation.log; then + echo "NIX_CFLAGS_COMPILE leaked into the flang wrapper" >&2 + exit 1 + fi + + # Confirm that NIX_FFLAGS_COMPILE is the user-facing channel for + # Fortran flags and flows through to the driver. + NIX_FFLAGS_COMPILE="-Iffflags-marker-include" \ + ${flangExe} -### -c hello.f90 > fflags-passthrough.log 2>&1 + grep -F -- "ffflags-marker-include" fflags-passthrough.log + + ${flangExe} -### -fbuiltin -fno-builtin hello.f90 > builtin.log 2>&1 + grep -F -- "warning: '-fbuiltin' is not valid for Fortran" builtin.log + grep -F -- "warning: '-fno-builtin' is not valid for Fortran" builtin.log + if grep -F -- "error: unknown argument" builtin.log; then + echo "builtin compatibility flags unexpectedly failed" >&2 + exit 1 + fi + + ${flangExe} -### -fexpensive-optimizations hello.f90 > ignored-flag.log 2>&1 + grep -F -- "optimization flag '-fexpensive-optimizations' is not supported" ignored-flag.log + if grep -F -- "error: unknown argument" ignored-flag.log; then + echo "ignored gfortran-style flag unexpectedly failed" >&2 + exit 1 + fi + + if ${flangExe} -### -complex-range=full hello.f90 > suggestion.log 2>&1; then + echo "expected -complex-range=full to fail at the driver layer" >&2 + exit 1 + fi + grep -F -- "error: unknown argument '-complex-range=full'" suggestion.log + grep -F -- "did you mean '-Xflang -complex-range=full'" suggestion.log + if grep -F -- "-Xclang -complex-range=full" suggestion.log; then + echo "driver suggested -Xclang instead of -Xflang" >&2 + exit 1 + fi + + touch $out + ''; +} diff --git a/pkgs/development/compilers/llvm/common/patches.nix b/pkgs/development/compilers/llvm/common/patches.nix index 30fa0411956a..7a780175c8cc 100644 --- a/pkgs/development/compilers/llvm/common/patches.nix +++ b/pkgs/development/compilers/llvm/common/patches.nix @@ -138,4 +138,24 @@ path = ../19; } ]; + "flang/warn-on-fbuiltin-and-fno-builtin.patch" = [ + { + after = "20"; + before = "22"; + path = ../21; + } + ]; + "flang/accept-and-ignore-some-gfortran-optimization-flags.patch" = [ + { + after = "20"; + before = "22"; + path = ../21; + } + ]; + "flang/use-xflang-in-diagnostics.patch" = [ + { + after = "20"; + path = ../21; + } + ]; }