Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ elif [[ $0 != *cpp ]]; then
fi
fi

if [[ "@darwinMinVersion@" ]]; then
if [[ "@darwinMinVersion@" ]] && [ "@isFlang@" != 1 ]; then
extraBefore+=(-Werror=unguarded-availability)
fi
23 changes: 22 additions & 1 deletion pkgs/build-support/cc-wrapper/cc-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ while (( "$n" < "$nParams" )); do

case "$p" in
-[cSEM] | -MM) dontLink=1 ;;
-cc1) cc1=1 ;;
-cc1 | -fc1 ) cc1=1 ;;
-nostdinc) cInclude=0 cxxInclude=0 ;;
-nostdinc++) cxxInclude=0 ;;
-nostdlib) cxxLibrary=0 ;;
Expand Down Expand Up @@ -218,6 +218,27 @@ if [[ -e @out@/nix-support/add-local-cc-cflags-before.sh ]]; then
source @out@/nix-support/add-local-cc-cflags-before.sh
fi

if [ "@isFlang@" = 1 ]; then
# Nix's reproducible-build hook injects -frandom-seed=..., but flang does
# not currently accept that option. Strip it here so the wrapper remains
# deterministic without surfacing a spurious flang driver failure.
kept=()
for p in ${extraBefore+"${extraBefore[@]}"}; do
if [[ "$p" != -frandom-seed=* ]]; then
kept+=("$p")
fi
done
extraBefore=(${kept+"${kept[@]}"})

kept=()
for p in ${extraAfter+"${extraAfter[@]}"}; do
if [[ "$p" != -frandom-seed=* ]]; then
kept+=("$p")
fi
done
extraAfter=(${kept+"${kept[@]}"})
fi

# As a very special hack, if the arguments are just `-v', then don't
# add anything. This is to prevent `gcc -v' (which normally prints
# out the version number and returns exit code 0) from printing out
Expand Down
40 changes: 26 additions & 14 deletions pkgs/build-support/cc-wrapper/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
nixSupport ? { },
isGNU ? false,
isClang ? cc.isClang or false,
isFlang ? cc.isFlang or false,
isZig ? cc.isZig or false,
isArocc ? cc.isArocc or false,
isCcache ? cc.isCcache or false,
Expand Down Expand Up @@ -385,7 +386,9 @@ let
#
# TODO: Drop `mangle-NIX_STORE-in-__FILE__.patch` from GCC and make
# this unconditional once the upstream bug is fixed.
useMacroPrefixMap = !isGNU;
useMacroPrefixMap = !isGNU && !isFlang;
systemIncludeFlag = if isFlang || isArocc then "-I" else "-idirafter";
fortifyIncludeFlag = if isFlang then "-I" else "-isystem";
in

assert includeFortifyHeaders' -> fortify-headers != null;
Expand Down Expand Up @@ -573,10 +576,18 @@ stdenvNoCC.mkDerivation {
''

+ optionalString cc.langFortran or false ''
wrap ${targetPrefix}gfortran $wrapper $ccPath/${targetPrefix}gfortran
ln -sv ${targetPrefix}gfortran $out/bin/${targetPrefix}g77
ln -sv ${targetPrefix}gfortran $out/bin/${targetPrefix}f77
export named_fc=${targetPrefix}gfortran
if [ -e $ccPath/${targetPrefix}gfortran ]; then
wrap ${targetPrefix}gfortran $wrapper $ccPath/${targetPrefix}gfortran
ln -sv ${targetPrefix}gfortran $out/bin/${targetPrefix}g77
ln -sv ${targetPrefix}gfortran $out/bin/${targetPrefix}f77
export named_fc=${targetPrefix}gfortran
elif [ -e $ccPath/${targetPrefix}flang ]; then
wrap ${targetPrefix}flang $wrapper $ccPath/${targetPrefix}flang
export named_fc=${targetPrefix}flang
elif [ -e $ccPath/flang ]; then
wrap ${targetPrefix}flang $wrapper $ccPath/flang
export named_fc=${targetPrefix}flang
fi
''

+ optionalString cc.langGo or false ''
Expand Down Expand Up @@ -712,19 +723,17 @@ stdenvNoCC.mkDerivation {
echo "-B${libc_lib}${libc.libdir or "/lib/"}" >> $out/nix-support/libc-crt1-cflags
''
+ ''
include "-${
if isArocc then "I" else "idirafter"
}" "${libc_dev}${libc.incdir or "/include"}" >> $out/nix-support/libc-cflags
include "${systemIncludeFlag}" "${libc_dev}${libc.incdir or "/include"}" >> $out/nix-support/libc-cflags
''
+ optionalString isGNU ''
for dir in "${cc}"/lib/gcc/*/*/include-fixed; do
include '-idirafter' ''${dir} >> $out/nix-support/libc-cflags
done
''
+ optionalString (libc.w32api or null != null) ''
echo '-idirafter ${lib.getDev libc.w32api}${
include "${systemIncludeFlag}" "${lib.getDev libc.w32api}${
libc.incdir or "/include/w32api"
}' >> $out/nix-support/libc-cflags
}" >> $out/nix-support/libc-cflags
''
+ ''

Expand All @@ -739,7 +748,7 @@ stdenvNoCC.mkDerivation {
# like option that forces the libc headers before all -idirafter,
# hence -isystem here.
+ optionalString includeFortifyHeaders' ''
include -isystem "${fortify-headers}/include" >> $out/nix-support/libc-cflags
include "${fortifyIncludeFlag}" "${fortify-headers}/include" >> $out/nix-support/libc-cflags
''
)

Expand All @@ -760,7 +769,7 @@ stdenvNoCC.mkDerivation {
# already knows how to find its own libstdc++, and adding
# additional -isystem flags will confuse gfortran (see
# https://github.com/NixOS/nixpkgs/pull/209870#issuecomment-1500550903)
+ optionalString (libcxx == null && isClang && (useGccForLibs && gccForLibs.langCC or false)) ''
+ optionalString (libcxx == null && isClang && useGccForLibs && (cc.langCC or false)) ''
for dir in ${gccForLibs}/include/c++/*; do
include -cxx-isystem "$dir" >> $out/nix-support/libcxx-cxxflags
done
Expand Down Expand Up @@ -827,6 +836,7 @@ stdenvNoCC.mkDerivation {
optionalString
(
(cc.isClang or false)
&& !isFlang
&& !(cc.isROCm or false)
&& !targetPlatform.isDarwin
&& !targetPlatform.isAndroid
Expand Down Expand Up @@ -861,7 +871,8 @@ stdenvNoCC.mkDerivation {
let
enable_fp = !targetPlatform.isx86_32 && !targetPlatform.isS390;
enable_leaf_fp =
enable_fp
!isFlang
&& enable_fp
&& (
targetPlatform.isx86_64
|| targetPlatform.isAarch64
Expand Down Expand Up @@ -927,7 +938,7 @@ stdenvNoCC.mkDerivation {
# well with multi line flags, so make the flags single line again
+ ''
for flags in "$out/nix-support"/*flags*; do
substituteInPlace "$flags" --replace $'\n' ' '
substituteInPlace "$flags" --replace-quiet $'\n' ' '
done

substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh
Expand Down Expand Up @@ -973,6 +984,7 @@ stdenvNoCC.mkDerivation {

env = {
inherit isClang;
inherit isFlang;

# for substitution in utils.bash
# TODO(@sternenseemann): invent something cleaner than passing in "" in case of absence
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
From da7174958be43d69b2ed6b581c8ac8a382b59180 Mon Sep 17 00:00:00 2001
From: Tarun Prabhu <tarun.prabhu@gmail.com>
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<clang_ignored_legacy_options_Group>;

// Group that ignores all gcc optimizations that won't be implemented
def clang_ignored_gcc_optimization_f_Group : OptionGroup<
- "<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>, Flags<[Ignored]>;
+ "<clang_ignored_gcc_optimization_f_Group>">,
+ Group<f_Group>, Flags<[Ignored]>, Visibility<[ClangOption, FlangOption]>;

class DiagnosticOpts<string base>
: 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();

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
From 9ab9d33171ee35c948967a2a2d714b8059887607 Mon Sep 17 00:00:00 2001
From: Tarun Prabhu <tarun@lanl.gov>
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 {
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
From 263377a175709c2d11f3ff63c2d2d2843afb91ea Mon Sep 17 00:00:00 2001
From: Tarun Prabhu <tarun@lanl.gov>
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<OptionIgnored>;
+def warn_drv_invalid_argument_for_flang : Warning<
+ "'%0' is not valid for Fortran">,
+ InGroup<OptionIgnored>;
def warn_drv_unsupported_option_for_flang : Warning<
"the argument '%0' is not supported for option '%1'. Mapping to '%1%2'">,
InGroup<OptionIgnored>;
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<SetFalse>>;
def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>,
- Visibility<[ClangOption, CLOption, DXCOption]>;
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption, FC1Option]>;
def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_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<CodeGenOpts<"AssumeSaneOperatorNew">>;
def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_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<f_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();

6 changes: 5 additions & 1 deletion pkgs/development/compilers/llvm/common/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
fixDarwinDylibNames,
enableManpages ? false,
enableClangToolsExtra ? true,
extraPatches ? [ ],
devExtraCmakeFlags ? [ ],
replaceVars,
getVersionFile,
Expand Down Expand Up @@ -73,7 +74,8 @@ stdenv.mkDerivation (
];
stripLen = 1;
hash = "sha256-1NKej08R9SPlbDY/5b0OKUsHjX07i9brR84yXiPwi7E=";
});
})
++ extraPatches;

nativeBuildInputs = [
cmake
Expand Down Expand Up @@ -189,6 +191,8 @@ stdenv.mkDerivation (
passthru = {
inherit libllvm;
isClang = true;
langC = true;
langCC = true;
hardeningUnsupportedFlagsByTargetPlatform =
targetPlatform:
[ "fortify3" ]
Expand Down
Loading
Loading