diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3505,7 +3505,6 @@ def m64 : Flag<["-"], "m64">, Group, Flags<[NoXarchOption, CoreOption]>; def maix64 : Flag<["-"], "maix64">, Group, Flags<[NoXarchOption]>; def mx32 : Flag<["-"], "mx32">, Group, Flags<[NoXarchOption, CoreOption]>; -def mabi_EQ : Joined<["-"], "mabi=">, Group; def miamcu : Flag<["-"], "miamcu">, Group, Flags<[NoXarchOption, CoreOption]>, HelpText<"Use Intel MCU ABI">; def mno_iamcu : Flag<["-"], "mno-iamcu">, Group, Flags<[NoXarchOption, CoreOption]>; @@ -3514,6 +3513,7 @@ def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group; let Flags = [TargetSpecific] in { +def mabi_EQ : Joined<["-"], "mabi=">, Group; def malign_branch_EQ : CommaJoined<["-"], "malign-branch=">, Group, HelpText<"Specify types of branches to align">; def malign_branch_boundary_EQ : Joined<["-"], "malign-branch-boundary=">, Group, @@ -3599,9 +3599,7 @@ let Flags = [TargetSpecific] in { def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group, Values<"soft,softfp,hard">; def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group; -} // let Flags = [TargetSpecific] def mfpu_EQ : Joined<["-"], "mfpu=">, Group; -let Flags = [TargetSpecific] in { def mhwdiv_EQ : Joined<["-"], "mhwdiv=">, Group; def mhwmult_EQ : Joined<["-"], "mhwmult=">, Group; } // let Flags = [TargetSpecific] diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -4879,7 +4879,8 @@ // In clang-cl, don't mention unknown arguments here since they have // already been warned about. if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) { - if (A->getOption().hasFlag(options::TargetSpecific)) { + if (A->getOption().hasFlag(options::TargetSpecific) && + !A->isIgnoredTargetSpecific()) { Diag(diag::err_drv_unsupported_opt_for_target) << A->getSpelling() << getTargetTriple(); } else { diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -139,4 +139,10 @@ // or the alias -m[no-]strict-align. AddTargetFeature(Args, Features, options::OPT_munaligned_access, options::OPT_mno_unaligned_access, "ual"); + + // Accept but warn about these TargetSpecific options. + if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ)) + A->ignoreTargetSpecific(); + if (Arg *A = Args.getLastArgNoClaim(options::OPT_mfpu_EQ)) + A->ignoreTargetSpecific(); } diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp --- a/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/clang/lib/Driver/ToolChains/MinGW.cpp @@ -701,6 +701,9 @@ << A->getSpelling() << GuardArgs; } } + + if (Arg *A = DriverArgs.getLastArgNoClaim(options::OPT_mthreads)) + A->ignoreTargetSpecific(); } void toolchains::MinGW::AddClangCXXStdlibIncludeArgs( diff --git a/llvm/include/llvm/Option/Arg.h b/llvm/include/llvm/Option/Arg.h --- a/llvm/include/llvm/Option/Arg.h +++ b/llvm/include/llvm/Option/Arg.h @@ -49,9 +49,15 @@ /// Was this argument used to effect compilation? /// - /// This is used for generating "argument unused" diagnostics. + /// This is used for generating an "argument unused" warning (without + /// clang::driver::options::TargetSpecific) or "unsupported option" error + /// (with TargetSpecific). mutable unsigned Claimed : 1; + /// Used with an unclaimed option with the TargetSpecific flag. If set, report + /// an "argument unused" warning instead of an "unsupported option" error. + mutable unsigned IgnoredTargetSpecific : 1; + /// Does this argument own its values? mutable unsigned OwnsValues : 1; @@ -104,10 +110,15 @@ void setOwnsValues(bool Value) const { OwnsValues = Value; } bool isClaimed() const { return getBaseArg().Claimed; } - - /// Set the Arg claimed bit. void claim() const { getBaseArg().Claimed = true; } + bool isIgnoredTargetSpecific() const { + return getBaseArg().IgnoredTargetSpecific; + } + void ignoreTargetSpecific() const { + getBaseArg().IgnoredTargetSpecific = true; + } + unsigned getNumValues() const { return Values.size(); } const char *getValue(unsigned N = 0) const { diff --git a/llvm/lib/Option/Arg.cpp b/llvm/lib/Option/Arg.cpp --- a/llvm/lib/Option/Arg.cpp +++ b/llvm/lib/Option/Arg.cpp @@ -20,19 +20,19 @@ Arg::Arg(const Option Opt, StringRef S, unsigned Index, const Arg *BaseArg) : Opt(Opt), BaseArg(BaseArg), Spelling(S), Index(Index), Claimed(false), - OwnsValues(false) {} + IgnoredTargetSpecific(false), OwnsValues(false) {} Arg::Arg(const Option Opt, StringRef S, unsigned Index, const char *Value0, const Arg *BaseArg) : Opt(Opt), BaseArg(BaseArg), Spelling(S), Index(Index), Claimed(false), - OwnsValues(false) { + IgnoredTargetSpecific(false), OwnsValues(false) { Values.push_back(Value0); } Arg::Arg(const Option Opt, StringRef S, unsigned Index, const char *Value0, const char *Value1, const Arg *BaseArg) : Opt(Opt), BaseArg(BaseArg), Spelling(S), Index(Index), Claimed(false), - OwnsValues(false) { + IgnoredTargetSpecific(false), OwnsValues(false) { Values.push_back(Value0); Values.push_back(Value1); }