Issue |
148297
|
Summary |
[Clang Tidy] Segmentation fault during AST parsing
|
Labels |
clang
|
Assignees |
|
Reporter |
erikbs
|
Platforms tested:
* macOS 15.5 (aarch64)
* macOS 11.6 (x86_64)
* RockyLinux 9.6 (x86_64)
LLVM/Clang versions tested:
* 20.1.7, obtained through MacPorts (on macOS)
* 20.1.1 and 20.1.8, built from source (from this repo) using company-internal script (on RockyLinux)
When running Clang Tidy on the given source file, it seems to crash when parsing its AST (`clang::ParseAST`). Regular compilation works (`cmake --build build/` succeeds).
The crash happens when running Clang Tidy 20 on the code given below and the configured compiler is Clang 20. If using for example Clang 19 as compiler, Clang Tidy 20 does not crash on this code. Using GCC’s libstdc++ does not trigger the crash either. Clang Tidy 19 does not seem to be affected, even using Clang 20 and its libc++ in `compile_commands.json`. This holds for both the macOS and the RockyLinux environments. Unfortunately only Clang Tidy on macOS gave me the backtrace, RockyLinux just says “Segmentation fault (core dumped)”. Clang Tidy output with backtrace (macOS 15.5):
```
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: /opt/local/libexec/llvm-20/bin/clang-tidy -p build/compile_commands.json lib.cpp
1. <eof> parser at end of file
#0 0x00000001155f3a10 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/local/libexec/llvm-20/lib/libLLVM.dylib+0x14fa10)
#1 0x00000001155f1c60 llvm::sys::RunSignalHandlers() (/opt/local/libexec/llvm-20/lib/libLLVM.dylib+0x14dc60)
#2 0x00000001155f407c SignalHandler(int) (/opt/local/libexec/llvm-20/lib/libLLVM.dylib+0x15007c)
#3 0x000000018d79c624 (/usr/lib/system/libsystem_platform.dylib+0x1804ac624)
#4 0x000000010b45a2ac clang::ento::ConditionBRVisitor::VisitTerminator(clang::Stmt const*, clang::ento::ExplodedNode const*, clang::CFGBlock const*, clang::CFGBlock const*, clang::ento::PathSensitiveBugReport&, clang::ento::BugReporterContext&) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1e1a2ac)
#5 0x000000010b45a07c clang::ento::ConditionBRVisitor::VisitNode(clang::ento::ExplodedNode const*, clang::ento::BugReporterContext&, clang::ento::PathSensitiveBugReport&) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1e1a07c)
#6 0x000000010b44cfdc generateVisitorsDiagnostics(clang::ento::PathSensitiveBugReport*, clang::ento::ExplodedNode const*, clang::ento::BugReporterContext&) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1e0cfdc)
#7 0x000000010b4473b0 clang::ento::PathSensitiveBugReporter::generatePathDiagnostics(llvm::ArrayRef<clang::ento::PathDiagnosticConsumer*>, llvm::ArrayRef<clang::ento::PathSensitiveBugReport*>&) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1e073b0)
#8 0x000000010b44bbcc clang::ento::PathSensitiveBugReporter::generateDiagnosticForConsumerMap(clang::ento::BugReport*, llvm::ArrayRef<clang::ento::PathDiagnosticConsumer*>, llvm::ArrayRef<clang::ento::BugReport*>) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1e0bbcc)
#9 0x000000010b445684 clang::ento::BugReporter::FlushReport(clang::ento::BugReportEquivClass&) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1e05684)
#10 0x000000010b4454ec clang::ento::BugReporter::FlushReports() (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1e054ec)
#11 0x000000010b708848 (anonymous namespace)::AnalysisConsumer::HandleCode(clang::Decl*, unsigned int, clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl const*, llvm::DenseMapInfo<clang::Decl const*, void>>*) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x20c8848)
#12 0x000000010b707100 (anonymous namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x20c7100)
#13 0x000000010b29add4 clang::MultiplexConsumer::HandleTranslationUnit(clang::ASTContext&) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1c5add4)
#14 0x0000000109813300 clang::ParseAST(clang::Sema&, bool, bool) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1d3300)
#15 0x000000010b25d6e8 clang::FrontendAction::Execute() (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1c1d6e8)
#16 0x000000010b1f0514 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1bb0514)
#17 0x000000010b3dbb0c clang::tooling::FrontendActionFactory::runInvocation(std::__1::shared_ptr<clang::CompilerInvocation>, clang::FileManager*, std::__1::shared_ptr<clang::PCHContainerOperations>, clang::DiagnosticConsumer*) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1d9bb0c)
#18 0x000000010498050c clang::tidy::runClangTidy(clang::tidy::ClangTidyContext&, clang::tooling::CompilationDatabase const&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>, bool, bool, llvm::StringRef)::ActionFactory::runInvocation(std::__1::shared_ptr<clang::CompilerInvocation>, clang::FileManager*, std::__1::shared_ptr<clang::PCHContainerOperations>, clang::DiagnosticConsumer*) (/opt/local/libexec/llvm-20/bin/clang-tidy+0x10000c50c)
#19 0x000000010b3db94c clang::tooling::ToolInvocation::runInvocation(char const*, clang::driver::Compilation*, std::__1::shared_ptr<clang::CompilerInvocation>, std::__1::shared_ptr<clang::PCHContainerOperations>) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1d9b94c)
#20 0x000000010b3da824 clang::tooling::ToolInvocation::run() (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1d9a824)
#21 0x000000010b3dd204 clang::tooling::ClangTool::run(clang::tooling::ToolAction*) (/opt/local/libexec/llvm-20/lib/libclang-cpp.dylib+0x1d9d204)
#22 0x000000010497b0b0 clang::tidy::runClangTidy(clang::tidy::ClangTidyContext&, clang::tooling::CompilationDatabase const&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>, bool, bool, llvm::StringRef) (/opt/local/libexec/llvm-20/bin/clang-tidy+0x1000070b0)
#23 0x00000001049b0530 clang::tidy::clangTidyMain(int, char const**) (/opt/local/libexec/llvm-20/bin/clang-tidy+0x10003c530)
#24 0x000000018d3c2b98
./ct.sh: line 5: 65414 Segmentation fault: 11 clang-tidy-mp-20 -p build/compile_commands.json lib.cpp
```
Steps to reproduce (note: MacPorts’ naming scheme for the executables):
1. Create `CMakeLists.txt` and `lib.cpp` as given below
2. Run `cmake -G Ninja -B build -S .` and `clang-tidy-mp-20 -p build/compile_commands.json lib.cpp`
CMakeLists.txt:
```cmake
cmake_minimum_required(VERSION 3.20)
set(CMAKE_C_COMPILER clang-mp-20)
set(CMAKE_CXX_COMPILER clang++-mp-20)
add_compile_options(-stdlib=libc++)
# This block of code was needed on macOS to prevent CMake from using Xcode’s libc++
# It is not necessary on RockyLinux
set(CMAKE_FIND_ROOT_PATH "/opt/local/libexec/llvm-20/include/c++/v1/")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_CXX_FLAGS "-nostdinc++ -I/opt/local/libexec/llvm-20/include/c++/v1")
set(CMAKE_EXE_LINKER_FLAGS "-L/opt/local/libexec/llvm-20/lib/libc++")
project(minimal_example)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_library(libexample OBJECT lib.cpp)
```
lib.cpp:
```c++
#include <memory>
struct Type1 {
Type1(const Type1&) { std::make_unique<int>(); }
Type1& operator=(const Type1&) {
if !consteval {}
return *this;
}
};
Type1* parse2();
auto parse() { return *parse2(); }
void func()
{
std::unique_ptr<Type1> type1;
*type1 = parse();
parse();
}
```
I have reduced the code as much as I was able to and did away with all third-party library dependencies. The call to `std::make_unique` is the only use of the standard library kept from the original program, except that `T` was not `int`. The crash can be triggered by making `type1` e.g. `std::optional<Type1>` or really any type that has an `operator*`, it seems (see below), but not by making it a regular pointer.
Removing or changing just about anything in the example code can make Clang Tidy not crash – even merging the declaration of variable `type1` with its assignment on the following line, swapping the last two lines of `func()` or deleting the pointless `if !consteval` or `std::make_unique<int>();`. There is also some flexibility that I do not understand. The last line _must_ be `parse()`, while the assignment line can use `*parse2()` instead of `parse()`. The assignment _must_ also be done on the first line after declaration of `type1`, but is optional on last line.
To eliminate all use of the standard library except `std::make_unique<int>()` (again the crash is only triggered if using libc++ from LLVM/Clang 20, so I believe this call to be relevant), `type1` can be defined as follows:
```c++
struct {
Type1& operator*();
} type1;
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs