Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[static analyser][StackAddrEscapeChecker] crash with std::function capturing a dangling reference #66221

Closed
SylvanBrocard opened this issue Sep 13, 2023 · 5 comments · Fixed by #66493
Labels
clang:static analyzer confirmed Verified by a second party

Comments

@SylvanBrocard
Copy link

When trying to analyze the following code with clang-tidy, I get a crash:

//minimal.cpp
#include <functional>

auto f() -> std::function<int()> {
  int v;
  auto c = [&v]() {
    return v;
  };
  return c;
}

auto main() -> int { return f()(); }

The function f returns a std::function wrapping a lambda with a dangling reference in its capture. The crash doesn't happen if I return a lambda instead of a std::function, nor if I capture by value.

Command

clang-tidy-16 minimal.cpp -- -std=c++20

Crash report:

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-16 minimal.cpp -- -std=c++23
1.      <eof> parser at end of file
2.      While analyzing stack: 
        #0 Calling f() at line 12
        #1 Calling main()
#0 0x00007fd657365796 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0xfc9796)
#1 0x00007fd6573639e0 llvm::sys::RunSignalHandlers() (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0xfc79e0)
#2 0x00007fd657365f6b (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0xfc9f6b)
#3 0x00007fd655ed5fd0 (/lib/x86_64-linux-gnu/libc.so.6+0x3bfd0)
#4 0x00007fd656387c50 vtable for __cxxabiv1::__si_class_type_info (/lib/x86_64-linux-gnu/libstdc++.so.6+0x20bc50)
Segmentation fault (core dumped)
$ clang-tidy-16 --version
Debian LLVM version 16.0.6
  Optimized build.

But the crash happens with clang-tidy 16, 17, 18, as well as the system 14.0.6 (inside a debian:latest docker) and the system 15.0.7 (on a Ubuntu 23.04 machine).

@PiotrZSL PiotrZSL added confirmed Verified by a second party and removed new issue labels Sep 13, 2023
@PiotrZSL
Copy link
Member

Crash is in:

#1  0x00005555591dfd2b in void clang::ento::check::EndFunction::_checkEndFunction<(anonymous namespace)::StackAddrEscapeChecker>(void*, clang::ReturnStmt const*, clang::ento::CheckerContext&) ()
#2  0x000055555931f3a8 in clang::ento::CheckerManager::runCheckersForEndFunction(clang::ento::NodeBuilderContext&, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNode*, clang::ento::ExprEngine&, clang::ReturnStmt const*) ()
#3  0x000055555934e601 in clang::ento::ExprEngine::processEndOfFunction(clang::ento::NodeBuilderContext&, clang::ento::ExplodedNode*, clang::ReturnStmt const*) ()
#4  0x0000555559327a3a in clang::ento::CoreEngine::HandleBlockEdge(clang::BlockEdge const&, clang::ento::ExplodedNode*) ()
#5  0x0000555559327364 in clang::ento::CoreEngine::dispatchWorkItem(clang::ento::ExplodedNode*, clang::ProgramPoint, clang::ento::WorkListUnit const&) ()
#6  0x0000555559327060 in clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>) ()
#7  0x0000555558f4dd23 in (anonymous namespace)::AnalysisConsumer::HandleCode(clang::Decl*, unsigned int, clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl const*, llvm::DenseMapInfo<clang::Decl const*, void> >*) ()
#8  0x0000555558f2ce51 in (anonymous namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&) ()

@PiotrZSL
Copy link
Member

PiotrZSL commented Sep 13, 2023

Crash is in:

# clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
400     // This cast supposed to succeed.
401     const VarRegion *ReferrerVar = cast<VarRegion>(Referrer->getBaseRegion());
402     const std::string ReferrerVarName =
403         ReferrerVar->getDecl()->getDeclName().getAsString();

We expect that we get VarRegion here but we geting CXXTempObjectRegion.
ReferrerVar = temp_object{std::function<int (void)>, S1246438}

And then we crash on getDecl() call that is virtual.

@PiotrZSL PiotrZSL changed the title [clang-tidy] crash with std::function capturing a dangling reference [static analyser][StackAddrEscapeChecker] crash with std::function capturing a dangling reference Sep 13, 2023
@llvmbot
Copy link
Member

llvmbot commented Sep 13, 2023

@llvm/issue-subscribers-clang-static-analyzer

When trying to analyze the following code with clang-tidy, I get a crash:
//minimal.cpp
#include <functional>

auto f() -> std::function<int()> {
  int v;
  auto c = [&v]() {
    return v;
  };
  return c;
}

auto main() -> int { return f()(); }

The function f returns a std::function wrapping a lambda with a dangling reference in its capture. The crash doesn't happen if I return a lambda instead of a std::function, nor if I capture by value.

Command

clang-tidy-16 minimal.cpp -- -std=c++20

Crash report:

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-16 minimal.cpp -- -std=c++23
1.      <eof> parser at end of file
2.      While analyzing stack: 
        #0 Calling f() at line 12
        #1 Calling main()
#0 0x00007fd657365796 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0xfc9796)
#1 0x00007fd6573639e0 llvm::sys::RunSignalHandlers() (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0xfc79e0)
#2 0x00007fd657365f6b (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0xfc9f6b)
#3 0x00007fd655ed5fd0 (/lib/x86_64-linux-gnu/libc.so.6+0x3bfd0)
#4 0x00007fd656387c50 vtable for __cxxabiv1::__si_class_type_info (/lib/x86_64-linux-gnu/libstdc++.so.6+0x20bc50)
Segmentation fault (core dumped)
$ clang-tidy-16 --version
Debian LLVM version 16.0.6
  Optimized build.

But the crash happens with clang-tidy 16, 17, 18, as well as the system 14.0.6 (inside a debian:latest docker) and the system 15.0.7 (on a Ubuntu 23.04 machine).

@steakhal
Copy link
Contributor

@PiotrZSL Could you post the preprocessed source for the reproducer?

@PiotrZSL
Copy link
Member

@steakhal it's the one in first post, i tested this on ubuntu.

steakhal added a commit that referenced this issue Sep 20, 2023
#66493)

Basically, the issue was that we should have unwrapped the
base region before we special handle temp object regions.

Fixes #66221

I also decided to add some extra range information to the diagnostics
to make it consistent with the other reporting path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:static analyzer confirmed Verified by a second party
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants