diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index c6496167d3828b9089c2419cd4725090a3f4d94e..84d2e7fa10b2c753deb3b5f59891a85970cfde93 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -355,6 +355,11 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE) endif () endif () +option(BUILD_FOR_OPENEULER "Add gcc compatible options for openEuler toolchain" OFF) +if (BUILD_FOR_OPENEULER) + add_definitions( -DBUILD_FOR_OPENEULER ) +endif() + # Determine HOST_LINK_VERSION on Darwin. set(HOST_LINK_VERSION) if (APPLE AND NOT CMAKE_LINKER MATCHES ".*lld.*") diff --git a/clang/include/clang/Basic/DiagnosticOptions.def b/clang/include/clang/Basic/DiagnosticOptions.def index 6d0c1b14acc12074e537b73d7e5b8596cdd0f21a..5253e951d40336c9eeaf1bf162e4af07e65aba90 100644 --- a/clang/include/clang/Basic/DiagnosticOptions.def +++ b/clang/include/clang/Basic/DiagnosticOptions.def @@ -99,6 +99,10 @@ VALUE_DIAGOPT(MessageLength, 32, 0) DIAGOPT(ShowSafeBufferUsageSuggestions, 1, 0) +#ifdef BUILD_FOR_OPENEULER +DIAGOPT(GccCompatible, 1, 0) /// -fgcc-compatible +#endif + #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 834a6f6cd43e32054cd08de706c9b5eb1838bd7a..1b7cb80a91a9a9db94840752a876c530f5afa560 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -525,6 +525,10 @@ BENIGN_LANGOPT(CheckConstexprFunctionBodies, 1, 1, LANGOPT(BoundsSafety, 1, 0, "Bounds safety extension for C") +#ifdef BUILD_FOR_OPENEULER +LANGOPT(GccCompatible, 1, 0, "Enable gcc compatibility for openEuler.") +#endif + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT diff --git a/clang/include/clang/Driver/CMakeLists.txt b/clang/include/clang/Driver/CMakeLists.txt index a9d988047920b0d845e69f0e03f1ef88b68d4556..ea55ba0f1f276d35943a2d96b9196f274bbf669d 100644 --- a/clang/include/clang/Driver/CMakeLists.txt +++ b/clang/include/clang/Driver/CMakeLists.txt @@ -1,3 +1,7 @@ set(LLVM_TARGET_DEFINITIONS Options.td) +if (BUILD_FOR_OPENEULER) +tablegen(LLVM Options.inc -gen-opt-parser-defs -DBUILD_FOR_OPENEULER) +else() tablegen(LLVM Options.inc -gen-opt-parser-defs) +endif() add_public_tablegen_target(ClangDriverOptions) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 15f9ee75492e3f95ccc03f995be6f7f91ba848e9..2c3f45b693e6e493f02c8d2b5ce15241a4e58b75 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1043,8 +1043,13 @@ def Xopenmp_target : Separate<["-"], "Xopenmp-target">, Group def Xopenmp_target_EQ : JoinedAndSeparate<["-"], "Xopenmp-target=">, Group, HelpText<"Pass to the target offloading toolchain identified by .">, MetaVarName<" ">; +#ifdef BUILD_FOR_OPENEULER +def z : JoinedOrSeparate<["-"], "z">, Flags<[LinkerInput]>, + HelpText<"Pass -z or -z to the linker">, MetaVarName<"">, +#else def z : Separate<["-"], "z">, Flags<[LinkerInput]>, HelpText<"Pass -z to the linker">, MetaVarName<"">, +#endif Group; def offload_link : Flag<["--"], "offload-link">, Group, HelpText<"Use the new offloading linker to perform the link job.">; @@ -2315,6 +2320,19 @@ def fmemory_profile_use_EQ : Joined<["-"], "fmemory-profile-use=">, HelpText<"Use memory profile for profile-guided memory optimization">, MarshallingInfoString>; +#ifdef BUILD_FOR_OPENEULER +def fgcc_compatible : Flag<["-"], "fgcc-compatible">, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, + MarshallingInfoFlag>, + HelpText<"Enable gcc compatibility for openEuler.">; +def fGNU_compatibility : Flag<["-"], "fGNU-compatibility">, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, + Alias, + HelpText<"Alias for -fgcc_compatible">; +def fno_gcc_compatible : Flag<["-"], "fno-gcc-compatible">, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>; +#endif + // Begin sanitizer flags. These should all be core options exposed in all driver // modes. let Visibility = [ClangOption, CC1Option, CLOption] in { @@ -6457,6 +6475,14 @@ def falign_jumps_EQ : Joined<["-"], "falign-jumps=">, Group, Group; +defm peephole2 : BooleanFFlag<"peephole2">, Group; +defm aggressive_loop_optiomizations : BooleanFFlag<"aggressive-loop-optiomizations">, Group; +def flto_partition_EQ : Joined<["-"], "flto-partition=">, Group; +#endif + defm check_new : BoolOption<"f", "check-new", LangOpts<"CheckNew">, DefaultFalse, PosFlag, diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index f9dc8ab24fa9d789042daaf95f1a8cbbd783b571..7ce7bb733acb79f9751b36ac72468cad0a6cba10 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1531,6 +1531,14 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { // Populate the tool chains for the offloading devices, if any. CreateOffloadingDeviceToolChains(*C, Inputs); +#ifdef BUILD_FOR_OPENEULER + if(C->getArgs().hasFlag(options::OPT_fgcc_compatible, + options::OPT_fno_gcc_compatible, false)) { + getDiags().setDiagnosticGroupWarningAsError("unused-command-line-argument", 0); + getDiags().setDiagnosticGroupWarningAsError("ignored-optimization-argument", 0); + } +#endif + // Construct the list of abstract actions to perform for this compilation. On // MachO targets this uses the driver-driver and universal actions. if (TC.getTriple().isOSBinFormatMachO()) @@ -2543,6 +2551,16 @@ void Driver::BuildUniversalActions(Compilation &C, const ToolChain &TC, } } +#ifdef BUILD_FOR_OPENEULER +llvm::DenseSet ZArgsList{ + "defs", "muldefs", "execstack", "noexecstack", "globalaudit", "combreloc", + "nocombreloc", "global", "initfirst", "interpose", "lazy", "loadfltr", + "nocopyreloc", "nodefaultlib", "nodelete", "nodlopen", "nodump", "now", + "origin", "relro", "norelro", "separate-code", "noseparate-code", "common", + "nocommon", "text", "notext", "textoff" +}; +#endif + bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value, types::ID Ty, bool TypoCorrect) const { if (!getCheckInputsExist()) @@ -2614,6 +2632,14 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value, if (IsCLMode() && Ty == types::TY_Object && !Value.starts_with("/")) return true; +#ifdef BUILD_FOR_OPENEULER + if (ZArgsList.find(Value) != ZArgsList.end() || + Value.starts_with("common-page-size=") || + Value.starts_with("max-page-size=") || + Value.starts_with("stack-size=")) + return true; +#endif + Diag(clang::diag::err_drv_no_such_file) << Value; return false; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 8858c318aba7a1ab4aa3bdda1fe4757afcf60710..0ff0b048227ebbc7de7a78d661590aad3f928f4e 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2764,6 +2764,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, CmdArgs.push_back(Value.data()); } else if (Value == "--version") { D.PrintVersion(C, llvm::outs()); + #ifdef BUILD_FOR_OPENEULER + } else if (Value.starts_with("--generate-missing-build-notes=") && + Args.hasFlag(options::OPT_fgcc_compatible, + options::OPT_fno_gcc_compatible, false)) { + // Do nothing. + #endif } else { D.Diag(diag::err_drv_unsupported_option_argument) << A->getSpelling() << Value; @@ -4983,6 +4989,50 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-triple"); CmdArgs.push_back(Args.MakeArgString(TripleStr)); +#ifdef BUILD_FOR_OPENEULER + if (Args.hasFlag(options::OPT_fgcc_compatible, + options::OPT_fno_gcc_compatible, false)) { + // compatibility relevent warnings + CmdArgs.push_back("-Wno-error=unknown-warning-option"); + CmdArgs.push_back("-Wno-error=ignored-attributes"); + // By default, clang reports warnings, but gcc does not. + CmdArgs.push_back("-Wno-error=unused-parameter"); + CmdArgs.push_back("-Wno-error=unused-function"); + CmdArgs.push_back("-Wno-error=unused-but-set-parameter"); + CmdArgs.push_back("-Wno-error=unused-but-set-variable"); + CmdArgs.push_back("-Wno-error=deprecated-non-prototype"); + CmdArgs.push_back("-Wno-error=unsafe-buffer-usage"); + CmdArgs.push_back("-Wno-error=string-plus-int"); + CmdArgs.push_back("-Wno-error=language-extension-token"); + CmdArgs.push_back("-Wno-error=single-bit-bitfield-constant-conversion"); + CmdArgs.push_back("-Wno-error=gnu-variable-sized-type-not-at-end"); + CmdArgs.push_back("-Wno-error=header-guard"); + CmdArgs.push_back("-Wno-error=return-type-c-linkage"); + // By default, clang reports errors, but gcc reports warnings. + // when -Werror is passed don't add -Wno-error=*. + if(!D.getDiags().getWarningsAsErrors()) { + CmdArgs.push_back("-Wno-error=implicit-function-declaration"); + CmdArgs.push_back("-Wno-error=incompatible-function-pointer-types"); + CmdArgs.push_back("-Wno-error=register"); + CmdArgs.push_back("-Wno-error=int-conversion"); + CmdArgs.push_back("-Wno-error=implicit-int"); + CmdArgs.push_back("-Wno-error=enum-constexpr-conversion"); + CmdArgs.push_back("-Wno-error=return-type"); + CmdArgs.push_back("-Wno-error=reserved-user-defined-literal"); + } + //other warnings + CmdArgs.push_back("-Wno-error=cast-align"); + CmdArgs.push_back("-Wno-error=enum-conversion"); + CmdArgs.push_back("-Wno-error=switch"); + CmdArgs.push_back("-Wno-error=cast-qual"); + CmdArgs.push_back("-Wno-error=varargs"); + CmdArgs.push_back("-Wno-error=unused-value"); + CmdArgs.push_back("-Wno-error=format-nonliteral"); + + CmdArgs.push_back("-fgcc-compatible"); + } +#endif + 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 028fdb2cc6b9dac7684fc16fab46d82b906f11f9..17759d7da6153151753a7ec92b230b87ccef507a 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -934,6 +934,37 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, OptSpecifier GroupWithValue, std::vector &Diagnostics) { for (auto *A : Args.filtered(Group)) { +#ifdef BUILD_FOR_OPENEULER + bool GccCompatible = Args.hasFlag(options::OPT_fgcc_compatible, + options::OPT_fno_gcc_compatible, false); + if (A->getOption().getKind() == Option::FlagClass) { + // The argument is a pure flag (such as OPT_Wall or + // OPT_Wdeprecated). Add its name (minus the "W" or "R" at the + // beginning) to the diagnostics. + if (A->getOption().getName() == "Wall" && GccCompatible) { + // Avoid -Wall and -Werror=format=2 override -Wno-xxx + Diagnostics.insert( + Diagnostics.begin(), + std::string(A->getOption().getName().drop_front(1))); + } else { + Diagnostics.push_back( + std::string(A->getOption().getName().drop_front(1))); + } + } else if (A->getOption().matches(GroupWithValue)) { + // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic + // group. Add only the group name to the diagnostics. + Diagnostics.push_back(std::string( + A->getOption().getName().drop_front(1).rtrim("=-"))); + } else { + // Otherwise, add its value (for OPT_W_Joined and similar). + if (std::string(A->getValue()) == "error=format=2" && GccCompatible) { + // Avoid -Werror=format=2 override -Wno-xxx + Diagnostics.insert(Diagnostics.begin(), A->getValue()); + } else { + Diagnostics.push_back(A->getValue()); + } + } +#else if (A->getOption().getKind() == Option::FlagClass) { // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add // its name (minus the "W" or "R" at the beginning) to the diagnostics. @@ -948,6 +979,7 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, // Otherwise, add its value (for OPT_W_Joined and similar). Diagnostics.push_back(A->getValue()); } +#endif } } @@ -3825,6 +3857,11 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, if (!Opts.RandstructSeed.empty()) GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed); + +#ifdef BUILD_FOR_OPENEULER + if (Opts.GccCompatible) + GenerateArg(Consumer, OPT_fgcc_compatible); +#endif } bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, @@ -4454,6 +4491,10 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str(); } +#ifdef BUILD_FOR_OPENEULER + Opts.GccCompatible = Args.hasArg(options::OPT_fgcc_compatible); +#endif + return Diags.getNumErrors() == NumErrorsBefore; } diff --git a/clang/test/Driver/test-generate-missing-build-notes.cpp b/clang/test/Driver/test-generate-missing-build-notes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..efd5251e6a1caca7a020fcb401cfaffcd724b41e --- /dev/null +++ b/clang/test/Driver/test-generate-missing-build-notes.cpp @@ -0,0 +1,13 @@ +// REQUIRES: build_for_openeuler +// RUN: %clang -### -fgcc-compatible -Wa,--generate-missing-build-notes=yes %s 2>&1 | FileCheck -check-prefix=CHECK-NO-ERROR %s +// RUN: %clang -### -fgcc-compatible -Wa,--generate-missing-build-notes=no %s 2>&1 | FileCheck -check-prefix=CHECK-NO-ERROR %s +// CHECK-NO-ERROR-NOT: --generate-missing-build-notes= +// RUN: %clang -### -Wa,--generate-missing-build-notes=yes %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s +// RUN: %clang -### -Wa,--generate-missing-build-notes=no %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s +// RUN: %clang -### -fno-gcc-compatible -Wa,--generate-missing-build-notes=yes %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s +// RUN: %clang -### -fno-gcc-compatible -Wa,--generate-missing-build-notes=no %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s +// CHECK-ERROR: error: unsupported argument '--generate-missing-build-notes= + +int main() { + return 1; +} diff --git a/clang/test/Driver/test-warnning.c b/clang/test/Driver/test-warnning.c new file mode 100644 index 0000000000000000000000000000000000000000..641f9e3512d5c016cf66006116e692c606310572 --- /dev/null +++ b/clang/test/Driver/test-warnning.c @@ -0,0 +1,15 @@ +// REQUIRES: build_for_openeuler + +// RUN: %clang -v -fgcc-compatible -Wno-format-security -Werror=format=2 -Wall %s +// RUN: %clang -v -Wall %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s +// CHECK-ERROR: warning: format string is not a string literal (potentially insecure) +// RUN: %clang -v -Wno-format-security -Werror=format=2 -Wall %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s +// CHECK-ERROR: error: format string is not a string literal (potentially insecure) + +#include + +int main() { + char *str = "llvm-project"; + printf(str); + return 0; +} \ No newline at end of file diff --git a/clang/test/Driver/z-args.c b/clang/test/Driver/z-args.c new file mode 100644 index 0000000000000000000000000000000000000000..83bb2b570e69aab8c70e70269ec5b9374ed4f55b --- /dev/null +++ b/clang/test/Driver/z-args.c @@ -0,0 +1,15 @@ +// REQUIRES: build_for_openeuler +// RUN: %clang -### -znow 2>&1 | FileCheck -check-prefix=CHECK-LINKER %s +// CHECK-LINKER: "-z" "now" + +// RUN: %clang -### -Wl,-z now 2>&1 | FileCheck -check-prefix=CHECK-WLCOMMAZ %s +// CHECK-WLCOMMAZ: "-z" "now" +// RUN: %clang -### -Wl,-z -Wl,now 2>&1 | FileCheck \ +// RUN: -check-prefix=CHECK-WLCOMMAZ1 %s +// CHECK-WLCOMMAZ1: "-z" "now" +// RUN: %clang -### -Wl,-z -O3 now 2>&1 | FileCheck \ +// RUN: -check-prefix=CHECK-WLCOMMAZ2 %s +// CHECK-WLCOMMAZ2: "-z" "now" +// RUN: %clang -### -Wl,-z stack-size=1 2>&1 | FileCheck \ +// RUN: -check-prefix=CHECK-WLCOMMAZ3 %s +// CHECK-WLCOMMAZ3: "-z" "stack-size=1" \ No newline at end of file diff --git a/clang/test/LibClang/symbols.test b/clang/test/LibClang/symbols.test index fd2ff8bc6cd423319d52aa7e22111b64b9eb2d52..e12b4c9991b811fed8f4822e7d3953ae51282fe7 100644 --- a/clang/test/LibClang/symbols.test +++ b/clang/test/LibClang/symbols.test @@ -1,6 +1,6 @@ # Check that there are no unversioned clang symbols in libclang.so RUN: llvm-nm -Dj --defined-only %libclang | grep -v -e '@@LLVM_[0-9]\+$' | not grep '^clang' -# Check that here are no local clang_ symbols (ignoring symbols with .cold or +# Check that there are no local clang_ symbols (ignoring symbols with .cold or # .localalias suffxies.) -RUN: llvm-nm %libclang | not grep '[a-z] clang_[^.]\+$' +RUN: llvm-nm %libclang | not grep '[a-z] clang_[^.$]\+$' diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index 1cbd876ac5bb93ad4debbba72a26cb92134a32cd..6f9fce15c3409c8cd1c99f809064b64e7de88cc3 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -44,6 +44,7 @@ config.standalone_build = @CLANG_BUILT_STANDALONE@ config.ppc_linux_default_ieeelongdouble = @PPC_LINUX_DEFAULT_IEEELONGDOUBLE@ config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@ config.substitutions.append(("%llvm-version-major", "@LLVM_VERSION_MAJOR@")) +config.build_for_openeuler = @BUILD_FOR_OPENEULER@ import lit.llvm lit.llvm.initialize(lit_config, config) diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index 5ca580fbb59c59a5a078989d755ee5a1ba8b24b3..60c59c282471e16f8baee9939eabb0cc63affc01 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -150,6 +150,13 @@ if(LLVM_RUNTIMES_GPU_BUILD) return() endif() +option(BUILD_FOR_OPENEULER "Build support for openeuler" OFF) +if(BUILD_FOR_OPENEULER) + set(BUILD_FOR_OPENEULER 1) +else() + set(BUILD_FOR_OPENEULER 0) +endif() + if(LLVM_ENABLE_EXPENSIVE_CHECKS) # When LLVM_ENABLE_EXPENSIVE_CHECKS is ON, LLVM will intercept errors # using assert(). An explicit check is performed here.