Closed
Description
Use of a function named strerror
in a private namespace causes clang-tidy to crash.
If the function is renamed to anything else (e.g. strerrorX
) the crash disappears.
Minimal program that shows this issue:
#include <string>
namespace other {
std::string strerror(int errnum);
void test() {
(void)strerror(0);
}
} // namespace other
Running this through clang-tidy in LLVM 18.1.2 leads to:
Error running 'clang-tidy': PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: clang-tidy -warnings-as-errors=* -header-filter=/home/ilyak/veo/crux -extra-arg=-Wpedantic -extra-arg=-Wno-sign-conversion -extra-arg=-Wno-unknown-pragmas -extra-arg-before=--target=x86_64-oe-linux -p=/home/ilyak/veo/crux/release.scarthgap --extra-arg-before=--driver-mode=g++ /home/ilyak/veo/crux/lib/thread/attrib.cpp -- /home/ilyak/veo/oe-scarthgap/tmp/build-glibc/sysroots/x86_64/usr/bin/x86_64-oe-linux/x86_64-oe-linux-g++ -m64 -march=x86-64-v3 --sysroot=/home/ilyak/veo/oe-scarthgap/tmp/build-glibc/sysroots/intel-skylake-64 --sysroot=/home/ilyak/veo/oe-scarthgap/tmp/build-glibc/sysroots/intel-skylake-64 -DBACKWARD_HAS_BACKTRACE=0 -DBACKWARD_HAS_BACKTRACE_SYMBOL=0 -DBACKWARD_HAS_BFD=0 -DBACKWARD_HAS_DW=1 -DBACKWARD_HAS_DWARF=0 -DBACKWARD_HAS_LIBUNWIND=0 -DBACKWARD_HAS_UNWIND=1 -DFMT_SHARED -Dthread_EXPORTS -I/home/ilyak/veo/crux/lib/thread/include -I/home/ilyak/veo/crux/lib/log/include -I/home/ilyak/veo/oe-scarthgap/tmp/build-glibc/sysroots/intel-skylake-64/usr/lib/backward -I/home/ilyak/veo/crux/lib/veofmt/include -O2 -pipe -g -feliminate-unused-debug-types -O3 -DNDEBUG -std=c++20 -fPIC -Wall -Wpedantic -Wconversion -Werror -Wextra -Wno-psabi -MD -MT lib/thread/CMakeFiles/thread.dir/attrib.cpp.o -MF CMakeFiles/thread.dir/attrib.cpp.o.d -o CMakeFiles/thread.dir/attrib.cpp.o -c /home/ilyak/veo/crux/lib/thread/attrib.cpp
1. <eof> parser at end of file
2. While analyzing stack:
#0 Calling other::test()
3. /home/ilyak/veo/crux/lib/thread/attrib.cpp:7:11: Error evaluating statement
4. /home/ilyak/veo/crux/lib/thread/attrib.cpp:7:11: Error evaluating statement
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 libLLVM.so.18.1 0x00007ef329b2c1a4 llvm::sys::RunSignalHandlers() + 52
1 libLLVM.so.18.1 0x00007ef329b2c456
2 libc.so.6 0x00007ef328a57270
3 libclang-cpp.so.18.1 0x00007ef331f62f43 clang::ento::MemRegion::getBaseRegion() const + 3
4 libclang-cpp.so.18.1 0x00007ef3320fd519
5 libclang-cpp.so.18.1 0x00007ef3320feb15
6 libclang-cpp.so.18.1 0x00007ef331edf053
7 libclang-cpp.so.18.1 0x00007ef331edf4aa clang::ento::CheckerManager::runCheckersForCallEvent(bool, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&, clang::ento::CallEvent const&, clang::ento::ExprEngine&, bool) + 90
8 libclang-cpp.so.18.1 0x00007ef331f40384 clang::ento::ExprEngine::evalCall(clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNode*, clang::ento::CallEvent const&) + 740
9 libclang-cpp.so.18.1 0x00007ef331f40c2a clang::ento::ExprEngine::VisitCallExpr(clang::CallExpr const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) + 506
10 libclang-cpp.so.18.1 0x00007ef331f16fe6 clang::ento::ExprEngine::Visit(clang::Stmt const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) + 1270
11 libclang-cpp.so.18.1 0x00007ef331f19ceb clang::ento::ExprEngine::ProcessStmt(clang::Stmt const*, clang::ento::ExplodedNode*) + 635
12 libclang-cpp.so.18.1 0x00007ef331f25572 clang::ento::ExprEngine::processCFGElement(clang::CFGElement, clang::ento::ExplodedNode*, unsigned int, clang::ento::NodeBuilderContext*) + 242
13 libclang-cpp.so.18.1 0x00007ef331ee7a1e clang::ento::CoreEngine::HandlePostStmt(clang::CFGBlock const*, unsigned int, clang::ento::ExplodedNode*) + 78
14 libclang-cpp.so.18.1 0x00007ef331ee7d9f clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>) + 223
15 libclang-cpp.so.18.1 0x00007ef332300347
16 libclang-cpp.so.18.1 0x00007ef33230e65f
17 libclang-cpp.so.18.1 0x00007ef331cbf668 clang::MultiplexConsumer::HandleTranslationUnit(clang::ASTContext&) + 40
18 libclang-cpp.so.18.1 0x00007ef32feacefd clang::ParseAST(clang::Sema&, bool, bool) + 1165
19 libclang-cpp.so.18.1 0x00007ef331c841b9 clang::FrontendAction::Execute() + 153
20 libclang-cpp.so.18.1 0x00007ef331c0e5b0 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 288
21 libclang-cpp.so.18.1 0x00007ef331e45204 clang::tooling::FrontendActionFactory::runInvocation(std::shared_ptr<clang::CompilerInvocation>, clang::FileManager*, std::shared_ptr<clang::PCHContainerOperations>, clang::DiagnosticConsumer*) + 340
22 clang-tidy 0x000000000169c685
23 libclang-cpp.so.18.1 0x00007ef331e3d905 clang::tooling::ToolInvocation::runInvocation(char const*, clang::driver::Compilation*, std::shared_ptr<clang::CompilerInvocation>, std::shared_ptr<clang::PCHContainerOperations>) + 101
24 libclang-cpp.so.18.1 0x00007ef331e4065d clang::tooling::ToolInvocation::run() + 1325
25 libclang-cpp.so.18.1 0x00007ef331e42610 clang::tooling::ClangTool::run(clang::tooling::ToolAction*) + 2080
26 clang-tidy 0x00000000016a7569 clang::tidy::runClangTidy(clang::tidy::ClangTidyContext&, clang::tooling::CompilationDatabase const&, llvm::ArrayRef<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>, bool, bool, llvm::StringRef) + 1001
27 clang-tidy 0x00000000008171c5 clang::tidy::clangTidyMain(int, char const**) + 2869
28 libc.so.6 0x00007ef328a41f3b
29 libc.so.6 0x00007ef328a41ff9 __libc_start_main + 137
30 clang-tidy 0x0000000000810c65 _start + 37
Segmentation fault
Note that this stack trace was produced when compiling exactly the minimal example in place of the original source that exhibited the issue. However, the same issue is currently also reproducible in clang-tidy (trunk) on godbolt.org:
https://godbolt.org/z/93Tqv4n8x
As an explanatory aside: our project uses a thread-safe wrapper for strerror
in a custom namespace that is implemented in terms of std::generic_category().message(errnum)
to appease concurrency-mt-unsafe
check.