Index: include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -119,6 +119,8 @@ def err_drv_optimization_remark_pattern : Error< "%0 in '%1'">; +def warn_linker_args_take_Wl : Warning<"linker argument -z should be -Wl,-z">, + InGroup; def warn_ignored_gcc_optimization : Warning<"ignoring unsupported optimization flag '%0'">, InGroup; def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup; Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -309,6 +309,8 @@ def Xclang : Separate<["-"], "Xclang">, HelpText<"Pass to the clang compiler">, MetaVarName<"">, Flags<[DriverOption, CoreOption]>; +def z_Flag : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>, + HelpText<"Pass -z to the linker">, MetaVarName<"">; def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>, HelpText<"Pass to the linker">, MetaVarName<"">; def Xpreprocessor : Separate<["-"], "Xpreprocessor">, Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -171,6 +171,7 @@ const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs) { const Driver &D = TC.getDriver(); + StringRef z_Flag("z"); // Add extra linker input arguments which are not treated as inputs // (constructed via -Xarch_). @@ -201,8 +202,14 @@ TC.AddCXXStdlibLibArgs(Args, CmdArgs); else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext)) TC.AddCCKextLibArgs(Args, CmdArgs); - else + else { + // Pass -z prefix for gcc linker compatibility. + if (A.getOption().getName().equals(z_Flag)) { + D.Diag(diag::warn_linker_args_take_Wl); + CmdArgs.push_back("-z"); + } A.renderAsInput(Args, CmdArgs); + } } // LIBRARY_PATH - included following the user specified library paths. @@ -7523,6 +7530,8 @@ const ArgList &Args, const char *LinkingOutput) const { ArgStringList CmdArgs; + StringRef z_Flag("z"); + const Driver &D = getToolChain().getDriver(); if (Output.isFilename()) { CmdArgs.push_back(Args.MakeArgString(std::string("-out:") + @@ -7574,8 +7583,14 @@ for (const auto &Input : Inputs) if (Input.isFilename()) CmdArgs.push_back(Input.getFilename()); - else - Input.getInputArg().renderAsInput(Args, CmdArgs); + else { + // Pass -z prefix for gcc linker compatibility. + if (Input.getInputArg().getOption().getName().equals(z_Flag)) { + D.Diag(diag::warn_linker_args_take_Wl); + CmdArgs.push_back("-z"); + } + Input.getInputArg().renderAsInput(Args, CmdArgs); + } const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("link.exe")); Index: test/Driver/Xlinker-args.c =================================================================== --- test/Driver/Xlinker-args.c +++ test/Driver/Xlinker-args.c @@ -3,22 +3,24 @@ // RUN: %clang -target i386-apple-darwin9 -### \ // RUN: -Xlinker one -Xlinker --no-demangle \ -// RUN: -Wl,two,--no-demangle,three -Xlinker four %s 2> %t +// RUN: -Wl,two,--no-demangle,three -Xlinker four -z five %s 2> %t // RUN: FileCheck -check-prefix=DARWIN < %t %s // // RUN: %clang -target x86_64-pc-linux-gnu -### \ // RUN: -Xlinker one -Xlinker --no-demangle \ -// RUN: -Wl,two,--no-demangle,three -Xlinker four %s 2> %t +// RUN: -Wl,two,--no-demangle,three -Xlinker four -z five %s 2> %t // RUN: FileCheck -check-prefix=LINUX < %t %s // // DARWIN-NOT: --no-demangle -// DARWIN: "one" "two" "three" "four" -// LINUX: "--no-demangle" "one" "two" "three" "four" +// DARWIN: "one" "two" "three" "four" "-z" "five" +// LINUX: "--no-demangle" "one" "two" "three" "four" "-z" "five" // Check that we forward '-Xlinker' and '-Wl,' on Windows. // RUN: %clang -target i686-pc-win32 -### \ -// RUN: -Xlinker one -Wl,two %s 2>&1 | \ -// RUN: FileCheck -check-prefix=WIN %s +// RUN: -Xlinker one -Wl,two -z three %s 2>&1 | \ +// RUN: FileCheck -check-prefix=WIN %s // WIN: link.exe // WIN: "one" // WIN: "two" +// WIN: "-z" +// WIN: "three" Index: test/Driver/clang_f_opts.c =================================================================== --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -172,16 +172,21 @@ // Test that the warning is displayed on these. // RUN: %clang -### -finline-limit=1000 %s 2>&1 | FileCheck --check-prefix=CHECK-WARNING1 %s // RUN: %clang -### -finline-limit %s 2>&1 | FileCheck --check-prefix=CHECK-WARNING2 %s +// RUN: %clang -### -z relro %s 2>&1 | FileCheck --check-prefix=CHECK-WARNING3 %s // CHECK-WARNING1: ignoring unsupported optimization flag '-finline-limit=1000' // CHECK-WARNING2: ignoring unsupported optimization flag '-finline-limit' +// CHECK-WARNING3: linker argument -z should be -Wl,-z // Test that we mute the warning on these // RUN: %clang -### -finline-limit=1000 -Wno-unused-command-line-argument \ // RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-NO-WARNING1 %s // RUN: %clang -### -finline-limit -Wno-unused-command-line-argument \ // RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-NO-WARNING2 %s +// RUN: %clang -### -z relro -Wno-invalid-command-line-argument \ +// RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-NO-WARNING3 %s // CHECK-NO-WARNING1-NOT: ignoring unsupported optimization flag '-finline-limit=1000' // CHECK-NO-WARNING2-NOT: ignoring unsupported optimization flag '-finline-limit' +// CHECK-NO-WARNING3-NOT: linker argument -z should be -Wl,-z // RUN: %clang -### -fshort-wchar -fno-short-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-WCHAR1 %s