llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.25k stars 12.08k forks source link

Assertion failure on expression statement: StaticAnalyzer/Core/ExprEngine.cpp:2240: virtual void clang::ento::ExprEngine::processEndOfFunction(clang::ento::NodeBuilderContext &, clang::ento::ExplodedNode *, const clang::ReturnStmt *): Assertion `I.first.g #41032

Open gribozavr opened 5 years ago

gribozavr commented 5 years ago
Bugzilla Link 41687
Version unspecified
OS All
CC @devincoughlin,@Szelethus

Extended Description

At SVN r359691:

$ cat /tmp/t.cc struct Foo {}; struct FooAndInt { FooAndInt(Foo, int) {} }; void entry(int x) { FooAndInt(Foo(), ({ return; x; })); }

$ ./bin/clang-tidy -checks="-,clang-analyzer" /tmp/t.cc Error while trying to load a compilation database: Could not auto-detect compilation database for file "/tmp/t.cc" No compilation database found in /tmp or any parent directory fixed-compilation-database: Error while opening fixed database: No such file or directory json-compilation-database: Error while opening JSON database: No such file or directory Running without flags. clang-tidy: llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:2240: virtual void clang::ento::ExprEngine::processEndOfFunction(clang::ento::NodeBuilderContext &, clang::ento::ExplodedNode , const clang::ReturnStmt ): Assertion `I.first.getItem().getKind() == ConstructionContextItem::TemporaryDestructorKind || I.first.getItem().getKind() == ConstructionContextItem::ElidedDestructorKind' failed.

​0 0x0000000000687f04 PrintStackTraceSignalHandler(void*) (./bin/clang-tidy+0x687f04)

​1 0x0000000000685c9c llvm::sys::RunSignalHandlers() (./bin/clang-tidy+0x685c9c)

​2 0x0000000000688448 SignalHandler(int) (./bin/clang-tidy+0x688448)

​3 0x00007fe1f4ca90c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x110c0)

​4 0x00007fe1f3833fcf raise (/lib/x86_64-linux-gnu/libc.so.6+0x32fcf)

​5 0x00007fe1f38353fa abort (/lib/x86_64-linux-gnu/libc.so.6+0x343fa)

​6 0x00007fe1f382ce37 (/lib/x86_64-linux-gnu/libc.so.6+0x2be37)

​7 0x00007fe1f382cee2 (/lib/x86_64-linux-gnu/libc.so.6+0x2bee2)

​8 0x0000000000da8bbf clang::ento::ExprEngine::processEndOfFunction(clang::ento::NodeBuilderContext&, clang::ento::ExplodedNode, clang::ReturnStmt const) (./bin/clang-tidy+0xda8bbf)

​9 0x0000000000d9020f clang::ento::CoreEngine::HandleBlockEdge(clang::BlockEdge const&, clang::ento::ExplodedNode*) (./bin/clang-tidy+0xd9020f)

​10 0x0000000000d8fbdd clang::ento::CoreEngine::dispatchWorkItem(clang::ento::ExplodedNode*, clang::ProgramPoint, clang::ento::WorkListUnit const&) (./bin/clang-tidy+0xd8fbdd)

​11 0x0000000000d8f7ab clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr) (./bin/clang-tidy+0xd8f7ab)

​12 0x0000000000b36c97 (anonymous namespace)::AnalysisConsumer::HandleCode(clang::Decl, unsigned int, clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl const, llvm::DenseMapInfo<clang::Decl const> >) (./bin/clang-tidy+0xb36c97)

​13 0x0000000000b2f815 (anonymous namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&) (./bin/clang-tidy+0xb2f815)

​14 0x0000000000f1f14c clang::MultiplexConsumer::HandleTranslationUnit(clang::ASTContext&) (./bin/clang-tidy+0xf1f14c)

​15 0x000000000107b5c3 clang::ParseAST(clang::Sema&, bool, bool) (./bin/clang-tidy+0x107b5c3)

​16 0x0000000000f071f0 clang::FrontendAction::Execute() (./bin/clang-tidy+0xf071f0)

​17 0x0000000000eac071 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (./bin/clang-tidy+0xeac071)

​18 0x0000000000a0d376 clang::tooling::FrontendActionFactory::runInvocation(std::shared_ptr, clang::FileManager, std::shared_ptr, clang::DiagnosticConsumer) (./bin/clang-tidy+0xa0d376)

​19 0x00000000006921d5 clang::tidy::runClangTidy(clang::tidy::ClangTidyContext&, clang::tooling::CompilationDatabase const&, llvm::ArrayRef<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, llvm::IntrusiveRefCntPtr, bool, llvm::StringRef)::ActionFactory::runInvocation(std::shared_ptr, clang::FileManager, std::shared_ptr, clang::DiagnosticConsumer) (./bin/clang-tidy+0x6921d5)

​20 0x0000000000a0d0e6 clang::tooling::ToolInvocation::runInvocation(char const, clang::driver::Compilation, std::shared_ptr, std::shared_ptr) (./bin/clang-tidy+0xa0d0e6)

​21 0x0000000000a0c997 clang::tooling::ToolInvocation::run() (./bin/clang-tidy+0xa0c997)

​22 0x0000000000a0e81e clang::tooling::ClangTool::run(clang::tooling::ToolAction*) (./bin/clang-tidy+0xa0e81e)

​23 0x000000000068eac3 clang::tidy::runClangTidy(clang::tidy::ClangTidyContext&, clang::tooling::CompilationDatabase const&, llvm::ArrayRef<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, llvm::IntrusiveRefCntPtr, bool, llvm::StringRef) (./bin/clang-tidy+0x68eac3)

​24 0x00000000004326bd clang::tidy::clangTidyMain(int, char const**) (./bin/clang-tidy+0x4326bd)

​25 0x00007fe1f38212b1 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b1)

​26 0x000000000043079a _start (./bin/clang-tidy+0x43079a)

Aborted

haoNoQ commented 5 years ago

I believe that this crash is different from llvm/llvm-project#40645 . This crash happens when we construct an argument of the call but then return before the call has even started; this way the value that we expected to materialize into the parameter variable never ends up materializing. We should also make sure that we call the destructor for this variable (assuming that statement-expressions do actually call the destructor in this scenario, which sounds plausible).

That's an interesting problem; i don't immediately see a really good solution here other than removing the assertion (and manually cleaning up the state) when we're returning from within a statement-expression.

We would still need to have the destructors in the CFG in order to invoke them. See also https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Statement-Exprs.html for how destructors are supposed to work. A few poor-man's solutions are possible here (such as simply escaping the pointers to objects that were not fully constructed) if we run into false positives after we fix the crash.

Szelethus commented 5 years ago

Managed to reproduce.

gribozavr commented 5 years ago

assigned to @haoNoQ

tom-github-account commented 1 year ago

I'm seeing this in my codebase with clang 15.0.3. @haoNoQ , you seem to have a pretty good handle on what's going on there, what are the prospects of this getting a fix? As a consumer of clang-tidy, I'd be much happier with some false positives than a crash!