[clang] 16524d2 - [Driver][AVR] Fix warn_drv_avr_stdlib_not_linked condition

Fangrui Song via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 28 09:43:44 PDT 2022


Author: Fangrui Song
Date: 2022-03-28T09:43:36-07:00
New Revision: 16524d2f1bdc2e74ca34425edf43ac8ef5d39531

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

LOG: [Driver][AVR] Fix warn_drv_avr_stdlib_not_linked condition

Many options (-fsyntax-only, -E, -S, etc) skip the link action phase which the
existing condition does not account for.

Since the code no longer specifies OPT_c, I think a single RUN line about -c
not leading to a warning is sufficient. Adding one for all of -E,
-fsyntax-only, -S would be excessive.

Reviewed By: benshi001

Differential Revision: https://reviews.llvm.org/D122553

Added: 
    

Modified: 
    clang/lib/Driver/ToolChains/AVR.cpp
    clang/lib/Driver/ToolChains/AVR.h
    clang/test/Driver/avr-toolchain.c

Removed: 
    clang/test/Driver/avr-link-no-mcu-specified.c


################################################################################
diff  --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp
index 8688e06e78cc3..8ca8525e454b4 100644
--- a/clang/lib/Driver/ToolChains/AVR.cpp
+++ b/clang/lib/Driver/ToolChains/AVR.cpp
@@ -366,49 +366,19 @@ const StringRef PossibleAVRLibcLocations[] = {
 /// AVR Toolchain
 AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple,
                            const ArgList &Args)
-    : Generic_ELF(D, Triple, Args), LinkStdlib(false) {
+    : Generic_ELF(D, Triple, Args) {
   GCCInstallation.init(Triple, Args);
 
   // Only add default libraries if the user hasn't explicitly opted out.
   if (!Args.hasArg(options::OPT_nostdlib) &&
-      !Args.hasArg(options::OPT_nodefaultlibs) &&
-      !Args.hasArg(options::OPT_c /* does not apply when not linking */)) {
-    std::string CPU = getCPUName(D, Args, Triple);
-
-    if (CPU.empty()) {
-      // We cannot link any standard libraries without an MCU specified.
-      D.Diag(diag::warn_drv_avr_mcu_not_specified);
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    if (GCCInstallation.isValid()) {
+      GCCInstallPath = GCCInstallation.getInstallPath();
+      std::string GCCParentPath(GCCInstallation.getParentLibPath());
+      getProgramPaths().push_back(GCCParentPath + "/../bin");
     } else {
-      Optional<StringRef> FamilyName = GetMCUFamilyName(CPU);
-      Optional<std::string> AVRLibcRoot = findAVRLibcInstallation();
-
-      if (!FamilyName.hasValue()) {
-        // We do not have an entry for this CPU in the family
-        // mapping table yet.
-        D.Diag(diag::warn_drv_avr_family_linking_stdlibs_not_implemented)
-            << CPU;
-      } else if (!GCCInstallation.isValid()) {
-        // No avr-gcc found and so no runtime linked.
-        D.Diag(diag::warn_drv_avr_gcc_not_found);
-      } else if (!AVRLibcRoot.hasValue()) {
-        // No avr-libc found and so no runtime linked.
-        D.Diag(diag::warn_drv_avr_libc_not_found);
-      } else { // We have enough information to link stdlibs
-        std::string GCCRoot(GCCInstallation.getInstallPath());
-        std::string GCCParentPath(GCCInstallation.getParentLibPath());
-        std::string LibcRoot = AVRLibcRoot.getValue();
-        std::string SubPath = GetMCUSubPath(CPU);
-
-        getProgramPaths().push_back(GCCParentPath + "/../bin");
-        getFilePaths().push_back(LibcRoot + std::string("/lib/") + SubPath);
-        getFilePaths().push_back(GCCRoot + std::string("/") + SubPath);
-
-        LinkStdlib = true;
-      }
+      D.Diag(diag::warn_drv_avr_gcc_not_found);
     }
-
-    if (!LinkStdlib)
-      D.Diag(diag::warn_drv_avr_stdlib_not_linked);
   }
 }
 
@@ -445,13 +415,14 @@ void AVRToolChain::addClangTargetOptions(
 }
 
 Tool *AVRToolChain::buildLinker() const {
-  return new tools::AVR::Linker(getTriple(), *this, LinkStdlib);
+  return new tools::AVR::Linker(getTriple(), *this);
 }
 
 void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                                const InputInfo &Output,
                                const InputInfoList &Inputs, const ArgList &Args,
                                const char *LinkingOutput) const {
+  const auto &TC = static_cast<const AVRToolChain &>(getToolChain());
   const Driver &D = getToolChain().getDriver();
 
   // Compute information about the target AVR.
@@ -473,6 +444,39 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   getToolChain().AddFilePathLibArgs(Args, CmdArgs);
 
+  // Only add default libraries if the user hasn't explicitly opted out.
+  bool LinkStdlib = false;
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    if (CPU.empty()) {
+      // We cannot link any standard libraries without an MCU specified.
+      D.Diag(diag::warn_drv_avr_mcu_not_specified);
+    } else {
+      Optional<StringRef> FamilyName = GetMCUFamilyName(CPU);
+      Optional<std::string> AVRLibcRoot = TC.findAVRLibcInstallation();
+
+      if (!FamilyName) {
+        // We do not have an entry for this CPU in the family
+        // mapping table yet.
+        D.Diag(diag::warn_drv_avr_family_linking_stdlibs_not_implemented)
+            << CPU;
+      } else if (!AVRLibcRoot) {
+        // No avr-libc found and so no runtime linked.
+        D.Diag(diag::warn_drv_avr_libc_not_found);
+      } else if (!TC.getGCCInstallPath().empty()) {
+        std::string SubPath = GetMCUSubPath(CPU);
+        CmdArgs.push_back(
+            Args.MakeArgString(Twine("-L") + *AVRLibcRoot + "/lib/" + SubPath));
+        CmdArgs.push_back(
+            Args.MakeArgString("-L" + TC.getGCCInstallPath() + "/" + SubPath));
+        LinkStdlib = true;
+      }
+    }
+
+    if (!LinkStdlib)
+      D.Diag(diag::warn_drv_avr_stdlib_not_linked);
+  }
+
   if (SectionAddressData.hasValue()) {
     std::string DataSectionArg = std::string("-Tdata=0x") +
                                  llvm::utohexstr(SectionAddressData.getValue());

diff  --git a/clang/lib/Driver/ToolChains/AVR.h b/clang/lib/Driver/ToolChains/AVR.h
index 2d027957ed766..ab147d852ad7c 100644
--- a/clang/lib/Driver/ToolChains/AVR.h
+++ b/clang/lib/Driver/ToolChains/AVR.h
@@ -31,17 +31,14 @@ class LLVM_LIBRARY_VISIBILITY AVRToolChain : public Generic_ELF {
                         llvm::opt::ArgStringList &CC1Args,
                         Action::OffloadKind DeviceOffloadKind) const override;
 
+  llvm::Optional<std::string> findAVRLibcInstallation() const;
+  StringRef getGCCInstallPath() const { return GCCInstallPath; }
+
 protected:
   Tool *buildLinker() const override;
 
 private:
-  /// Whether libgcc, libct, and friends should be linked.
-  ///
-  /// This is not done if the user does not specify a
-  /// microcontroller on the command line.
-  bool LinkStdlib;
-
-  llvm::Optional<std::string> findAVRLibcInstallation() const;
+  StringRef GCCInstallPath;
 };
 
 } // end namespace toolchains
@@ -50,9 +47,8 @@ namespace tools {
 namespace AVR {
 class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
 public:
-  Linker(const llvm::Triple &Triple, const ToolChain &TC, bool LinkStdlib)
-      : Tool("AVR::Linker", "avr-ld", TC), Triple(Triple),
-        LinkStdlib(LinkStdlib) {}
+  Linker(const llvm::Triple &Triple, const ToolChain &TC)
+      : Tool("AVR::Linker", "avr-ld", TC), Triple(Triple) {}
 
   bool hasIntegratedCPP() const override { return false; }
   bool isLinkJob() const override { return true; }
@@ -63,7 +59,6 @@ class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
 
 protected:
   const llvm::Triple &Triple;
-  bool LinkStdlib;
 };
 } // end namespace AVR
 } // end namespace tools

diff  --git a/clang/test/Driver/avr-link-no-mcu-specified.c b/clang/test/Driver/avr-link-no-mcu-specified.c
deleted file mode 100644
index 1c77099ebad98..0000000000000
--- a/clang/test/Driver/avr-link-no-mcu-specified.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: %clang -### -target avr -no-canonical-prefixes -save-temps %s 2>&1 | FileCheck --check-prefix=WARN %s
-// RUN: %clang -### -target avr -no-canonical-prefixes -save-temps -mmcu=atmega328 %s 2>&1 | FileCheck --check-prefix=NOWARN %s
-
-// WARN: warning: no target microcontroller specified on command line, cannot link standard libraries, please pass -mmcu=<mcu name>
-// WARN: warning: standard library not linked and so no interrupt vector table or compiler runtime routines will be linked
-
-// NOWARN: main
-
-int main() { return 0; }
-

diff  --git a/clang/test/Driver/avr-toolchain.c b/clang/test/Driver/avr-toolchain.c
index 50f62c34ff9e8..4e357e9811f35 100644
--- a/clang/test/Driver/avr-toolchain.c
+++ b/clang/test/Driver/avr-toolchain.c
@@ -35,3 +35,11 @@
 // RUN: %clang %s -### -target avr --sysroot %S/Inputs/basic_avr_tree 2>&1 -nostdinc | FileCheck --check-prefix=NOSTDINC %s
 // RUN: %clang %s -### -target avr --sysroot %S/Inputs/basic_avr_tree 2>&1 -nostdlibinc | FileCheck --check-prefix=NOSTDINC %s
 // NOSTDINC-NOT: "-internal-isystem" {{".*avr/include"}}
+
+// RUN: %clang -### --target=avr %s 2>&1 | FileCheck --check-prefix=WARN_STDLIB %s
+// RUN: %clang -### --target=avr -mmcu=atmega328 %s 2>&1 | FileCheck --check-prefix=NOWARN_STDLIB %s
+// RUN: %clang -### --target=avr -c %s 2>&1 | FileCheck --check-prefix=NOWARN_STDLIB %s
+
+// WARN_STDLIB: warning: no target microcontroller specified on command line, cannot link standard libraries, please pass -mmcu=<mcu name>
+// WARN_STDLIB: warning: standard library not linked and so no interrupt vector table or compiler runtime routines will be linked
+// NOWARN_STDLIB-NOT: warning:


        


More information about the cfe-commits mailing list