diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -23,6 +23,10 @@ namespace driver { namespace tools { +bool isPIE(const ToolChain &TC, const llvm::opt::ArgList &Args); +bool isStaticPIE(const ToolChain &TC, const llvm::opt::ArgList &Args); +bool isStatic(const llvm::opt::ArgList &Args); + void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -146,6 +146,37 @@ return TargetFeatureArg.getOption().matches(options::OPT_mno_cumode); } +bool tools::isPIE(const ToolChain &TC, const ArgList &Args) { + if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_r) || Args.hasArg(options::OPT_static_pie)) + return false; + + Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, + options::OPT_nopie); + if (!A) + return TC.isPIEDefault(Args); + return A->getOption().matches(options::OPT_pie); +} + +bool tools::isStaticPIE(const ToolChain &TC, const ArgList &Args) { + bool HasStaticPIE = Args.hasArg(options::OPT_static_pie); + // -no-pie is an alias for -nopie. So, handling -nopie takes care of + // -no-pie as well. + if (HasStaticPIE && Args.hasArg(options::OPT_nopie)) { + const Driver &D = TC.getDriver(); + const llvm::opt::OptTable &Opts = D.getOpts(); + StringRef StaticPIEName = Opts.getOptionName(options::OPT_static_pie); + StringRef NoPIEName = Opts.getOptionName(options::OPT_nopie); + D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName; + } + return HasStaticPIE; +} + +bool tools::isStatic(const ArgList &Args) { + return Args.hasArg(options::OPT_static) && + !Args.hasArg(options::OPT_static_pie); +} + void tools::addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths) { if (D.getVFS().exists(Path)) diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp --- a/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -71,7 +71,7 @@ if (!D.SysRoot.empty()) CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); - if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r)) + if (isPIE(ToolChain, Args)) CmdArgs.push_back("-pie"); if (Args.hasArg(options::OPT_rdynamic)) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -315,37 +315,6 @@ } } -static bool getPIE(const ArgList &Args, const ToolChain &TC) { - if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_r) || Args.hasArg(options::OPT_static_pie)) - return false; - - Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, - options::OPT_nopie); - if (!A) - return TC.isPIEDefault(Args); - return A->getOption().matches(options::OPT_pie); -} - -static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) { - bool HasStaticPIE = Args.hasArg(options::OPT_static_pie); - // -no-pie is an alias for -nopie. So, handling -nopie takes care of - // -no-pie as well. - if (HasStaticPIE && Args.hasArg(options::OPT_nopie)) { - const Driver &D = TC.getDriver(); - const llvm::opt::OptTable &Opts = D.getOpts(); - StringRef StaticPIEName = Opts.getOptionName(options::OPT_static_pie); - StringRef NoPIEName = Opts.getOptionName(options::OPT_nopie); - D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName; - } - return HasStaticPIE; -} - -static bool getStatic(const ArgList &Args) { - return Args.hasArg(options::OPT_static) && - !Args.hasArg(options::OPT_static_pie); -} - void tools::gnutools::StaticLibTool::ConstructJob( Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -410,9 +379,9 @@ const bool isAndroid = ToolChain.getTriple().isAndroid(); const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU(); const bool IsVE = ToolChain.getTriple().isVE(); - const bool IsPIE = getPIE(Args, ToolChain); - const bool IsStaticPIE = getStaticPIE(Args, ToolChain); - const bool IsStatic = getStatic(Args); + const bool IsPIE = isPIE(ToolChain, Args); + const bool IsStaticPIE = isStaticPIE(ToolChain, Args); + const bool IsStatic = isStatic(Args); const bool HasCRTBeginEndFiles = ToolChain.getTriple().hasEnvironment() || (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies); diff --git a/clang/test/Driver/fuchsia.c b/clang/test/Driver/fuchsia.c --- a/clang/test/Driver/fuchsia.c +++ b/clang/test/Driver/fuchsia.c @@ -75,6 +75,14 @@ // RUN: | FileCheck %s -check-prefix=CHECK-RTLIB // CHECK-RTLIB: error: invalid runtime library name in argument '-rtlib=libgcc' +// RUN: %clang -### %s --target=x86_64-unknown-fuchsia -pie -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-PIE +// CHECK-PIE: "-pie" + +// RUN: %clang -### %s --target=x86_64-unknown-fuchsia -nopie -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOPIE +// CHECK-NOPIE-NOT: "-pie" + // RUN: %clang -### %s --target=x86_64-unknown-fuchsia -static -fuse-ld=lld 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-STATIC // CHECK-STATIC: "-Bstatic"