diff --git a/clang/include/clang/Basic/DiagnosticOptions.def b/clang/include/clang/Basic/DiagnosticOptions.def index 7be81f6b6a9541546896ab5abccea553a721e3b3..4ad691188a69e892f3dfbd19692c53d3cc184b72 100644 --- a/clang/include/clang/Basic/DiagnosticOptions.def +++ b/clang/include/clang/Basic/DiagnosticOptions.def @@ -95,6 +95,8 @@ VALUE_DIAGOPT(TabStop, 32, DefaultTabStop) /// The distance between tab stops. /// Column limit for formatting message diagnostics, or 0 if unused. VALUE_DIAGOPT(MessageLength, 32, 0) +DIAGOPT(GccCompatible, 1, 0) /// -fgcc_compatible + #undef DIAGOPT #undef ENUM_DIAGOPT #undef VALUE_DIAGOPT diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index ad366821f3cbff1153654f2bcad21381fa14313c..ee547b38130f1c2ef82264dc0d67cecf61411fc9 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -449,6 +449,8 @@ ENUM_LANGOPT(ExtendIntArgs, ExtendArgsKind, 1, ExtendArgsKind::ExtendTo32, VALUE_LANGOPT(FuchsiaAPILevel, 32, 0, "Fuchsia API level") +LANGOPT(GccCompatible, 1, 0, "Enable gcc compatibility.") + // This option will be removed in the future once the backend // supports all operations (like division or float-to-integer conversion) // on large _BitInts. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 3cab37b21aaf3f4bee4daecb21bd90d3cb5cf069..cffa38d83d0e3b55740a1050cd18d49506ac634b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -522,6 +522,12 @@ defvar std = !strconcat("LangStandard::getLangStandardForKind(", lang_std.KeyPat // Developer Driver Options +def fgcc_compatible : Flag<["-"], "fgcc-compatible">, Group, + MarshallingInfoFlag>, Flags<[CC1Option, NoArgumentUnused]>, + HelpText<"Enable gcc compatibility.">; +def fno_gcc_compatible : Flag<["-"], "fno-gcc-compatible">, Group, + Flags<[CC1Option, NoArgumentUnused]>; + def internal_Group : OptionGroup<"">, Flags<[HelpHidden]>; def internal_driver_Group : OptionGroup<"">, Group, HelpText<"DRIVER OPTIONS">; diff --git a/clang/lib/Basic/Warnings.cpp b/clang/lib/Basic/Warnings.cpp index cc8c138233ca1d9fcc4ef04840b87fb2efb94655..8d0095b6645ecf47b08d3490ae643602a4796530 100644 --- a/clang/lib/Basic/Warnings.cpp +++ b/clang/lib/Basic/Warnings.cpp @@ -29,6 +29,10 @@ #include using namespace clang; +#include +std::set GccCompatibleWhitelist{"stringop-overflow", + "maybe-uninitialized"}; + // EmitUnknownDiagWarning - Emit a warning and typo hint for unknown warning // opts static void EmitUnknownDiagWarning(DiagnosticsEngine &Diags, @@ -129,6 +133,11 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, continue; } + if (Opts.GccCompatible) { + if (GccCompatibleWhitelist.find(std::string(Opt)) != GccCompatibleWhitelist.end()) + continue; + } + // -Werror/-Wno-error is a special case, not controlled by the option // table. It also has the "specifier" form of -Werror=foo. GCC supports // the deprecated -Werror-implicit-function-declaration which is used by diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3704ed8586682677882acb8e1b82bfc14b1d07a5..6dbe535bea371d739cc0e765dd9b90c1843746df 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4542,6 +4542,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-triple"); CmdArgs.push_back(Args.MakeArgString(TripleStr)); + if (Args.hasFlag(options::OPT_fgcc_compatible, + options::OPT_fno_gcc_compatible, false)) { + CmdArgs.push_back("-Wno-error=int-conversion"); + CmdArgs.push_back("-Wno-unused-private-field"); + CmdArgs.push_back("-Wno-empty-body"); + CmdArgs.push_back("-Wno-pointer-to-enum-cast"); + CmdArgs.push_back("-Wno-unused-but-set-variable"); + Args.AddLastArg(CmdArgs, options::OPT_fgcc_compatible, + options::OPT_fno_gcc_compatible); + } + if (const Arg *MJ = Args.getLastArg(options::OPT_MJ)) { DumpCompilationDatabase(C, MJ->getValue(), TripleStr, Output, Input, Args); Args.ClaimAllArgs(options::OPT_MJ); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2dd96e68bb92fe19691f642f9fca4c3b44fbd2a8..62924edcade00d7624c35f3719b618a1da8d2e56 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3557,6 +3557,9 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts, if (!Opts.RandstructSeed.empty()) GenerateArg(Args, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed, SA); + + if(Opts.GccCompatible) + GenerateArg(Args, OPT_fgcc_compatible, SA); } bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, @@ -4107,6 +4110,10 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ)) Opts.RandstructSeed = A->getValue(0); + Opts.GccCompatible = Args.hasArg(options::OPT_fgcc_compatible, + options::OPT_fno_gcc_compatible, + /*Default=*/false); + return Diags.getNumErrors() == NumErrorsBefore; } diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 5310db3c882bc688d643d16126591584ce10d425..2921a22cc73e5c1af69a3c0adeff40b2371ee324 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -1448,6 +1448,9 @@ void Preprocessor::emitMacroDeprecationWarning(const Token &Identifier) const { assert(A.DeprecationInfo && "Macro deprecation warning without recorded annotation!"); const MacroAnnotationInfo &Info = *A.DeprecationInfo; + if (getLangOpts().GccCompatible) + if (Identifier.getIdentifierInfo()->isStr("ATOMIC_VAR_INIT")) + return; if (Info.Message.empty()) Diag(Identifier, diag::warn_pragma_deprecated_macro_use) << Identifier.getIdentifierInfo() << 0;