[clang] ae623d1 - [Driver,Gnu] Simplify -static -static-pie -shared -pie handling and suppress -shared -rdynamic warning

2023-11-17 Thread Fangrui Song via cfe-commits

Author: Fangrui Song
Date: 2023-11-16T13:48:04-08:00
New Revision: ae623d16d50c9f12de7ae7ac1aa11c9d6857e081

URL: 
https://github.com/llvm/llvm-project/commit/ae623d16d50c9f12de7ae7ac1aa11c9d6857e081
DIFF: 
https://github.com/llvm/llvm-project/commit/ae623d16d50c9f12de7ae7ac1aa11c9d6857e081.diff

LOG: [Driver,Gnu] Simplify -static -static-pie -shared -pie handling and 
suppress -shared -rdynamic warning

These options select different link modes (note: -shared -static can be
used together for musl and mingw). It makes sense to place them
together, which enables some simplification. The relevant ld options
are now consistently placed after -m, similar to GCC.

While here, suppress -Wunused-command-line-argument warning when -shared
-rdynamic are used together (introduced by commit
291f4a00232b5742940d67e2ecf9168631251317). It can be argued either way
whether the warning is justified (in ELF linkers --export-dynamic
functionality is subsumed by -shared), but it is not useful (users can
do -Wl,--export-dynamic, bypassing the driver diagnostic).

Added: 


Modified: 
clang/lib/Driver/ToolChains/Gnu.cpp
clang/test/Driver/dynamic-linker.c
clang/test/Driver/linux-ld.c
clang/test/Driver/ohos.c

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 76986481686adc6..ba95ce9c5a28153 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -292,18 +292,6 @@ static const char *getLDMOption(const llvm::Triple , 
const ArgList ) {
   }
 }
 
-static bool getPIE(const ArgList , const ToolChain ) {
-  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 , const ToolChain ) {
   bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
   // -no-pie is an alias for -nopie. So, handling -nopie takes care of
@@ -386,7 +374,6 @@ void tools::gnutools::Linker::ConstructJob(Compilation , 
const JobAction ,
   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 HasCRTBeginEndFiles =
@@ -406,17 +393,6 @@ void tools::gnutools::Linker::ConstructJob(Compilation , 
const JobAction ,
   if (!D.SysRoot.empty())
 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
 
-  if (IsPIE)
-CmdArgs.push_back("-pie");
-
-  if (IsStaticPIE) {
-CmdArgs.push_back("-static");
-CmdArgs.push_back("-pie");
-CmdArgs.push_back("--no-dynamic-linker");
-CmdArgs.push_back("-z");
-CmdArgs.push_back("text");
-  }
-
   if (Args.hasArg(options::OPT_s))
 CmdArgs.push_back("-s");
 
@@ -451,19 +427,32 @@ void tools::gnutools::Linker::ConstructJob(Compilation 
, const JobAction ,
   if (Triple.isRISCV())
 CmdArgs.push_back("-X");
 
-  if (Args.hasArg(options::OPT_shared))
+  const bool IsShared = Args.hasArg(options::OPT_shared);
+  if (IsShared)
 CmdArgs.push_back("-shared");
-
-  if (IsStatic) {
+  bool IsPIE = false;
+  if (IsStaticPIE) {
+CmdArgs.push_back("-static");
+CmdArgs.push_back("-pie");
+CmdArgs.push_back("--no-dynamic-linker");
+CmdArgs.push_back("-z");
+CmdArgs.push_back("text");
+  } else if (IsStatic) {
 CmdArgs.push_back("-static");
-  } else if (!Args.hasArg(options::OPT_r) &&
- !Args.hasArg(options::OPT_shared) && !IsStaticPIE) {
+  } else if (!Args.hasArg(options::OPT_r)) {
 if (Args.hasArg(options::OPT_rdynamic))
   CmdArgs.push_back("-export-dynamic");
-
-CmdArgs.push_back("-dynamic-linker");
-CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) +
- ToolChain.getDynamicLinker(Args)));
+if (!IsShared) {
+  Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie,
+   options::OPT_nopie);
+  IsPIE = A ? A->getOption().matches(options::OPT_pie)
+: ToolChain.isPIEDefault(Args);
+  if (IsPIE)
+CmdArgs.push_back("-pie");
+  CmdArgs.push_back("-dynamic-linker");
+  CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) +
+   ToolChain.getDynamicLinker(Args)));
+}
   }
 
   CmdArgs.push_back("-o");

diff  --git a/clang/test/Driver/dynamic-linker.c 
b/clang/test/Driver/dynamic-linker.c
index 555e46aba5f069b..978907e0adee697 100644
--- 

[clang] ae623d1 - [Driver,Gnu] Simplify -static -static-pie -shared -pie handling and suppress -shared -rdynamic warning

2023-11-16 Thread Fangrui Song via cfe-commits

Author: Fangrui Song
Date: 2023-11-16T13:48:04-08:00
New Revision: ae623d16d50c9f12de7ae7ac1aa11c9d6857e081

URL: 
https://github.com/llvm/llvm-project/commit/ae623d16d50c9f12de7ae7ac1aa11c9d6857e081
DIFF: 
https://github.com/llvm/llvm-project/commit/ae623d16d50c9f12de7ae7ac1aa11c9d6857e081.diff

LOG: [Driver,Gnu] Simplify -static -static-pie -shared -pie handling and 
suppress -shared -rdynamic warning

These options select different link modes (note: -shared -static can be
used together for musl and mingw). It makes sense to place them
together, which enables some simplification. The relevant ld options
are now consistently placed after -m, similar to GCC.

While here, suppress -Wunused-command-line-argument warning when -shared
-rdynamic are used together (introduced by commit
291f4a00232b5742940d67e2ecf9168631251317). It can be argued either way
whether the warning is justified (in ELF linkers --export-dynamic
functionality is subsumed by -shared), but it is not useful (users can
do -Wl,--export-dynamic, bypassing the driver diagnostic).

Added: 


Modified: 
clang/lib/Driver/ToolChains/Gnu.cpp
clang/test/Driver/dynamic-linker.c
clang/test/Driver/linux-ld.c
clang/test/Driver/ohos.c

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 76986481686adc6..ba95ce9c5a28153 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -292,18 +292,6 @@ static const char *getLDMOption(const llvm::Triple , 
const ArgList ) {
   }
 }
 
-static bool getPIE(const ArgList , const ToolChain ) {
-  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 , const ToolChain ) {
   bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
   // -no-pie is an alias for -nopie. So, handling -nopie takes care of
@@ -386,7 +374,6 @@ void tools::gnutools::Linker::ConstructJob(Compilation , 
const JobAction ,
   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 HasCRTBeginEndFiles =
@@ -406,17 +393,6 @@ void tools::gnutools::Linker::ConstructJob(Compilation , 
const JobAction ,
   if (!D.SysRoot.empty())
 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
 
-  if (IsPIE)
-CmdArgs.push_back("-pie");
-
-  if (IsStaticPIE) {
-CmdArgs.push_back("-static");
-CmdArgs.push_back("-pie");
-CmdArgs.push_back("--no-dynamic-linker");
-CmdArgs.push_back("-z");
-CmdArgs.push_back("text");
-  }
-
   if (Args.hasArg(options::OPT_s))
 CmdArgs.push_back("-s");
 
@@ -451,19 +427,32 @@ void tools::gnutools::Linker::ConstructJob(Compilation 
, const JobAction ,
   if (Triple.isRISCV())
 CmdArgs.push_back("-X");
 
-  if (Args.hasArg(options::OPT_shared))
+  const bool IsShared = Args.hasArg(options::OPT_shared);
+  if (IsShared)
 CmdArgs.push_back("-shared");
-
-  if (IsStatic) {
+  bool IsPIE = false;
+  if (IsStaticPIE) {
+CmdArgs.push_back("-static");
+CmdArgs.push_back("-pie");
+CmdArgs.push_back("--no-dynamic-linker");
+CmdArgs.push_back("-z");
+CmdArgs.push_back("text");
+  } else if (IsStatic) {
 CmdArgs.push_back("-static");
-  } else if (!Args.hasArg(options::OPT_r) &&
- !Args.hasArg(options::OPT_shared) && !IsStaticPIE) {
+  } else if (!Args.hasArg(options::OPT_r)) {
 if (Args.hasArg(options::OPT_rdynamic))
   CmdArgs.push_back("-export-dynamic");
-
-CmdArgs.push_back("-dynamic-linker");
-CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) +
- ToolChain.getDynamicLinker(Args)));
+if (!IsShared) {
+  Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie,
+   options::OPT_nopie);
+  IsPIE = A ? A->getOption().matches(options::OPT_pie)
+: ToolChain.isPIEDefault(Args);
+  if (IsPIE)
+CmdArgs.push_back("-pie");
+  CmdArgs.push_back("-dynamic-linker");
+  CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) +
+   ToolChain.getDynamicLinker(Args)));
+}
   }
 
   CmdArgs.push_back("-o");

diff  --git a/clang/test/Driver/dynamic-linker.c 
b/clang/test/Driver/dynamic-linker.c
index 555e46aba5f069b..978907e0adee697 100644
---