| Issue |
55530
|
| Summary |
[clang-tidy] `bugprone-unchecked-optional-access` crashes, hangs
|
| Labels |
clang-tidy,
crash,
crash-on-valid
|
| Assignees |
|
| Reporter |
whisperity
|
> Due to the interaction with dataflow, I was suggested by @steakhal to tag @Xazax-hun, @sgatev and @ymand. @ymand is also the author of the check.
When analysing "relatively complex"(?) code with `clang-tidy`, the `bugprone-unchecked-optional-access` checker either hangs, fails with seemingly infinite recursion, or crashes with a non-infinite stack trace.
Running nightly PPA on Ubuntu 20.04 LTS:
```
Package: clang-tidy-15
Version: 1:15~++20220513052831+6716e2055dde-1~exp1~20220513172924.250
```
# Non-infinite stack trace
> [ERROR 2022-05-17 11:45] - Analyzing [SmallIndexMapTest.cpp](http://github.com/whisperity/monomux/blob/99b1cafde9cb0fa915897ab0987ee246e9fa8fde/test/adt/SmallIndexMapTest.cpp) with clang-tidy failed!
```
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.Program arguments: /usr/lib/llvm-15/bin/clang-tidy /mnt/test/adt/SmallIndexMapTest.cpp --export-fixes /mnt/Reports/fixit/SmallIndexMapTest.cpp_clang-tidy_edc91faa5cbe120c7656946b7203686b.yaml -- -Qunused-arguments -Wall -Wextra -x c++ --target=x86_64-linux-gnu -I/mnt/include/core -I/mnt/include/implementation -I/mnt/AnalBuild/include -I/mnt/include -I/mnt/src -isystem /mnt/AnalBuild/_deps/googletest-src/googletest/include -isystem /mnt/AnalBuild/_deps/googletest-src/googletest -std=c++17 -isystem /usr/include/c++/9 -isystem /usr/include/x86_64-linux-gnu/c++/9 -isystem /usr/include/c++/9/backward -isystem /usr/local/include -isystem /usr/include/x86_64-linux-gnu -isystem /usr/include
1.<eof> parser at end of file
2.ASTMatcher: Processing 'bugprone-unchecked-optional-access' against:
CXXMethodDecl monomux::SmallIndexMap<int, 4, true, false>::isMapped : </mnt/include/core/monomux/adt/SmallIndexMap.hpp:352:3, line:358:3>
--- Bound Nodes Begin ---
T - { BuiltinType : int }
fun - { CXXMethodDecl monomux::SmallIndexMap<int, 4, true, false>::isMapped : </mnt/include/core/monomux/adt/SmallIndexMap.hpp:352:3, line:358:3> }
--- Bound Nodes End ---
#0 0x00007f55d774eff1 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0xe64ff1)
#1 0x00007f55d774cd3e llvm::sys::RunSignalHandlers() (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0xe62d3e)
#2 0x00007f55d774f51b (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0xe6551b)
#3 0x00007f55e0d3e420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
#4 0x00007f55df1a9c44 clang::dataflow::Environment::setValue(clang::dataflow::StorageLocation const&, clang::dataflow::Value&) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x1df2c44)
#5 0x00007f55df1bf294 (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x1e08294)
#6 0x00007f55df1c196c (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x1e0a96c)
#7 0x00007f55df1c5248 (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x1e0e248)
#8 0x00007f55df1bccf3 clang::dataflow::UncheckedOptionalAccessModel::transfer(clang::Stmt const*, clang::dataflow::SourceLocationsLattice&, clang::dataflow::Environment&) (/usr/lib/llvm-15/
bin/../lib/libclang-cpp.so.15+0x1e05cf3)
#9 0x00007f55df1b0ee1 clang::dataflow::transferBlock(clang::dataflow::ControlFlowContext const&, std::vector<llvm::Optional<clang::dataflow::TypeErasedDataflowAnalysisState>, std::allocator
<llvm::Optional<clang::dataflow::TypeErasedDataflowAnalysisState>>>&, clang::CFGBlock const&, clang::dataflow::Environment const&, clang::dataflow::TypeErasedDataflowAnalysis&, std::function
<void (clang::CFGStmt const&, clang::dataflow::TypeErasedDataflowAnalysisState const&)>) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x1df9ee1)
#10 0x00007f55df1b1684 clang::dataflow::runTypeErasedDataflowAnalysis(clang::dataflow::ControlFlowContext const&, clang::dataflow::TypeErasedDataflowAnalysis&, clang::dataflow::Environment c
onst&) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x1dfa684)
#11 0x000055932a5d6094 llvm::Expected<std::vector<llvm::Optional<clang::dataflow::DataflowAnalysisState<clang::dataflow::UncheckedOptionalAccessModel::Lattice>>, std::allocator<llvm::Optiona
l<clang::dataflow::DataflowAnalysisState<clang::dataflow::UncheckedOptionalAccessModel::Lattice>>>>> clang::dataflow::runDataflowAnalysis<clang::dataflow::UncheckedOptionalAccessModel>(clang
::dataflow::ControlFlowContext const&, clang::dataflow::UncheckedOptionalAccessModel&, clang::dataflow::Environment const&) (/usr/lib/llvm-15/bin/clang-tidy+0x398094)
#12 0x000055932a5d5b19 clang::tidy::bugprone::UncheckedOptionalAccessCheck::check(clang::ast_matchers::MatchFinder::MatchResult const&) (/usr/lib/llvm-15/bin/clang-tidy+0x397b19)
#13 0x00007f55de47892c (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c192c)
#14 0x00007f55de4ac31c clang::ast_matchers::internal::BoundNodesTreeBuilder::visitMatches(clang::ast_matchers::internal::BoundNodesTreeBuilder::Visitor*) (/usr/lib/llvm-15/bin/../lib/libclan
g-cpp.so.15+0x10f531c)
#15 0x00007f55de47834e (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c134e)
#16 0x00007f55de47af6f (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c3f6f)
#17 0x00007f55de47f57b (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c857b)
#18 0x00007f55de47b16e (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c416e)
#19 0x00007f55de47e346 (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c7346)
#20 0x00007f55de47b4fe (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c44fe)
#21 0x00007f55de47cedb (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c5edb)
#22 0x00007f55de47b0c6 (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c40c6)
#23 0x00007f55de48388b (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10cc88b)
#24 0x00007f55de47afa7 (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x10c3fa7)
#25 0x00007f55de44af71 clang::ast_matchers::MatchFinder::matchAST(clang::ASTContext&) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x1093f71)
#26 0x00007f55dfa1132c clang::MultiplexConsumer::HandleTranslationUnit(clang::ASTContext&) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x265a32c)
#27 0x00007f55dde085a4 clang::ParseAST(clang::Sema&, bool, bool) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0xa515a4)
#28 0x00007f55df9d4297 clang::FrontendAction::Execute() (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x261d297)
#29 0x00007f55df94ac96 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x2593c96)
#30 0x00007f55dfbe484c clang::tooling::FrontendActionFactory::runInvocation(std::shared_ptr<clang::CompilerInvocation>, clang::FileManager*, std::shared_ptr<clang::PCHContainerOperations>, c
lang::DiagnosticConsumer*) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x282d84c)
#31 0x000055932aa46f7d (/usr/lib/llvm-15/bin/clang-tidy+0x808f7d)
#32 0x00007f55dfbe45af clang::tooling::ToolInvocation::runInvocation(char const*, clang::driver::Compilation*, std::shared_ptr<clang::CompilerInvocation>, std::shared_ptr<clang::PCHContainer
Operations>) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x282d5af)
#33 0x00007f55dfbe3635 clang::tooling::ToolInvocation::run() (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x282c635)
#34 0x00007f55dfbe603e clang::tooling::ClangTool::run(clang::tooling::ToolAction*) (/usr/lib/llvm-15/bin/../lib/libclang-cpp.so.15+0x282f03e)
#35 0x000055932aa426ed 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) (/usr/lib/llvm-15/bin/clang-tidy+0x8046ed)
#36 0x000055932a446257 clang::tidy::clangTidyMain(int, char const**) (/usr/lib/llvm-15/bin/clang-tidy+0x208257)
#37 0x00007f55d63ce083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#38 0x000055932a4421de _start (/usr/lib/llvm-15/bin/clang-tidy+0x2041de)
```
The affected `isMapped()` function looks like this:
```cpp
/// \returns whether the stored element represents a mapped value.
bool isMapped(const E& Elem) const noexcept
{
if constexpr (IntrusiveDefaultSentinel)
return Elem != E{};
else
return static_cast<bool>(Elem);
}
```
where `E` is either some type like `int` or `T*` in case `IntrusiveDefaultSentinel` is `true`, and `std::unique_ptr<T>` or `std::optional<T>` otherwise. Both are castable to `bool` and are false when "empty".
# Infinite recursion depth
> [ERROR 2022-05-17 12:22] - Analyzing [Dispatch.cpp](http://github.com/whisperity/monomux/blob/99b1cafde9cb0fa915897ab0987ee246e9fa8fde/src/client/Dispatch.cpp) with clang-tidy failed!
I observed a crash with a seemingly infinite stack trace.
```
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.Program arguments: /usr/lib/llvm-15/bin/clang-tidy /mnt/src/client/Dispatch.cpp --export-fixes /mnt/Reports/fixit/Dispatch.cpp_clang-tidy_76b81b409a195383fc3c434ff5b14a4b.yaml -- -Qu
nused-arguments -Wall -Wextra -x c++ --target=x86_64-linux-gnu -I/mnt/include/core -I/mnt/include/implementation -I/mnt/AnalBuild/include -I/mnt/src -std=c++17 -isystem /usr/include/c++/9 -i
system /usr/include/x86_64-linux-gnu/c++/9 -isystem /usr/include/c++/9/backward -isystem /usr/local/include -isystem /usr/include/x86_64-linux-gnu -isystem /usr/include
1.<eof> parser at end of file
2.ASTMatcher: Processing 'bugprone-unchecked-optional-access' against:
CXXMethodDecl monomux::client::Client::responseClientID : </mnt/src/client/Dispatch.cpp:50:1 <Spelling=line:42:3>, line:59:1>
--- Bound Nodes Begin ---
T - { RecordType : monomux::message::response::ClientID }
fun - { CXXMethodDecl monomux::client::Client::responseClientID : </mnt/src/client/Dispatch.cpp:50:1 <Spelling=line:42:3>, line:59:1> }
--- Bound Nodes End ---
#0 0x00007f7284b07ff1 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0xe64ff1)
#1 0x00007f7284b05d3e llvm::sys::RunSignalHandlers() (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0xe62d3e)
#2 0x00007f7284b0851b (/usr/lib/llvm-15/bin/../lib/libLLVM-15.so.1+0xe6551b)
#3 0x00007f728e0f7420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
#4 0x00007f728c55fd5b clang::dataflow::DataflowAnalysisContext::addTransitiveFlowConditionConstraints(clang::dataflow::AtomicBoolValue&, llvm::DenseSet<clang::dataflow::BoolValue*, llvm::D
enseMapInfo<clang::dataflow::BoolValue*, void>>&, llvm::DenseSet<clang::dataflow::AtomicBoolValue*, llvm::DenseMapInfo<clang::dataflow::AtomicBoolValue*, void>>&) const (/usr/lib/llvm-15/bin
/../lib/libclang-cpp.so.15+0x1defd5b)
[#4 repeated until #255 where the stack printout stops]
```
The affected code snippet is generated partially from a macro:
```cpp
#define HANDLER(NAME) \
void Client::NAME(Client& Client, std::string_view Message)
#define MSG(TYPE) \
std::optional<TYPE> Msg = TYPE::decode(Message); \
if (!Msg) \
return;
HANDLER(responseClientID)
{
MSG(response::ClientID);
Client.ClientID = Msg->Client.ID;
/* ... unrelated code ... */
}
```
# Non-halting (?) execution
While the first crashes happened almost immediately and the second one happened after about 20 minutes of execution time, the last analysis job that I am running for my project, for a file that has a similar pattern to the 2nd case, has been running ~100% CPU use, currently at 496M resident memory, for about 80 minutes already.
-----
Disabling the check or running Tidy with just other checks makes the analyses conclude successfully. With every *other* check used by the project (*and* also running Clang SA), the **total** analysis time is about 7 minutes.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs