From: Timm Bäder Date: Tue, 2 Feb 2021 17:25:36 +0000 (+0100) Subject: [clang][driver] Only warn once about invalid library values X-Git-Tag: llvmorg-14-init~15581 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a6439b52088b1d58d8e7aa9891c9011648710593;p=platform%2Fupstream%2Fllvm.git [clang][driver] Only warn once about invalid library values Since ToolChain::GetCXXStdlibType() is a simple getter that might emit the "invalid library name in argument" warning, it can conceivably be called several times while initializing the build pipeline. Before this patch, a simple 'clang++ -stdlib=foo ./test.cpp' would print the warning twice, -rt=lib=foo would print 6 times. Change this and always only print the warning once. Keep the rest of the semantics of the functions. Differential Revision: https://reviews.llvm.org/D95915 --- diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 59fdd29..fed688c 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -166,6 +166,10 @@ private: EffectiveTriple = std::move(ET); } + mutable llvm::Optional cxxStdlibType; + mutable llvm::Optional runtimeLibType; + mutable llvm::Optional unwindLibType; + protected: MultilibSet Multilibs; Multilib SelectedMultilib; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index c8363808..d0f404d 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -884,66 +884,86 @@ void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args, ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( const ArgList &Args) const { + if (runtimeLibType) + return *runtimeLibType; + const Arg* A = Args.getLastArg(options::OPT_rtlib_EQ); StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_RTLIB; // Only use "platform" in tests to override CLANG_DEFAULT_RTLIB! if (LibName == "compiler-rt") - return ToolChain::RLT_CompilerRT; + runtimeLibType = ToolChain::RLT_CompilerRT; else if (LibName == "libgcc") - return ToolChain::RLT_Libgcc; + runtimeLibType = ToolChain::RLT_Libgcc; else if (LibName == "platform") - return GetDefaultRuntimeLibType(); + runtimeLibType = GetDefaultRuntimeLibType(); + else { + if (A) + getDriver().Diag(diag::err_drv_invalid_rtlib_name) + << A->getAsString(Args); - if (A) - getDriver().Diag(diag::err_drv_invalid_rtlib_name) << A->getAsString(Args); + runtimeLibType = GetDefaultRuntimeLibType(); + } - return GetDefaultRuntimeLibType(); + return *runtimeLibType; } ToolChain::UnwindLibType ToolChain::GetUnwindLibType( const ArgList &Args) const { + if (unwindLibType) + return *unwindLibType; + const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ); StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB; if (LibName == "none") - return ToolChain::UNW_None; + unwindLibType = ToolChain::UNW_None; else if (LibName == "platform" || LibName == "") { ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args); if (RtLibType == ToolChain::RLT_CompilerRT) - return ToolChain::UNW_None; + unwindLibType = ToolChain::UNW_None; else if (RtLibType == ToolChain::RLT_Libgcc) - return ToolChain::UNW_Libgcc; + unwindLibType = ToolChain::UNW_Libgcc; } else if (LibName == "libunwind") { if (GetRuntimeLibType(Args) == RLT_Libgcc) getDriver().Diag(diag::err_drv_incompatible_unwindlib); - return ToolChain::UNW_CompilerRT; + unwindLibType = ToolChain::UNW_CompilerRT; } else if (LibName == "libgcc") - return ToolChain::UNW_Libgcc; + unwindLibType = ToolChain::UNW_Libgcc; + else { + if (A) + getDriver().Diag(diag::err_drv_invalid_unwindlib_name) + << A->getAsString(Args); - if (A) - getDriver().Diag(diag::err_drv_invalid_unwindlib_name) - << A->getAsString(Args); + unwindLibType = GetDefaultUnwindLibType(); + } - return GetDefaultUnwindLibType(); + return *unwindLibType; } ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ + if (cxxStdlibType) + return *cxxStdlibType; + const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB; // Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB! if (LibName == "libc++") - return ToolChain::CST_Libcxx; + cxxStdlibType = ToolChain::CST_Libcxx; else if (LibName == "libstdc++") - return ToolChain::CST_Libstdcxx; + cxxStdlibType = ToolChain::CST_Libstdcxx; else if (LibName == "platform") - return GetDefaultCXXStdlibType(); + cxxStdlibType = GetDefaultCXXStdlibType(); + else { + if (A) + getDriver().Diag(diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); - if (A) - getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); + cxxStdlibType = GetDefaultCXXStdlibType(); + } - return GetDefaultCXXStdlibType(); + return *cxxStdlibType; } /// Utility function to add a system include directory to CC1 arguments. diff --git a/clang/test/Driver/undefined-libs.cpp b/clang/test/Driver/undefined-libs.cpp new file mode 100644 index 0000000..25a1532 --- /dev/null +++ b/clang/test/Driver/undefined-libs.cpp @@ -0,0 +1,15 @@ + +// Check that all the following options print a warning when given a non-existent +// value. But only one warning. + +// RUN: not %clangxx -stdlib=nostdlib %s 2>&1 | FileCheck --check-prefix=STDLIB %s +// STDLIB: error: invalid library name in argument '-stdlib=nostdlib' +// STDLIB-EMPTY: +// +// RUN: not %clangxx -rtlib=nortlib %s 2>&1 | FileCheck --check-prefix=RTLIB %s +// RTLIB: error: invalid runtime library name in argument '-rtlib=nortlib' +// RTLIB-EMPTY: +// +// RUN: not %clangxx -unwindlib=nounwindlib %s 2>&1 | FileCheck --check-prefix=UNWINDLIB %s +// UNWINDLIB: error: invalid unwind library name in argument '-unwindlib=nounwindlib' +// UNWINDLIB-EMPTY: