[all-commits] [llvm/llvm-project] 6ad47e: [analyzer] Catch leaking stack addresses via stack...

Balazs Benics via All-commits all-commits at lists.llvm.org
Fri Aug 27 02:31:44 PDT 2021


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 6ad47e1c4fbfa8a752cb711acdf242fed3f16a68
      https://github.com/llvm/llvm-project/commit/6ad47e1c4fbfa8a752cb711acdf242fed3f16a68
  Author: Balazs Benics <balazs.benics at sigmatechnology.se>
  Date:   2021-08-27 (Fri, 27 Aug 2021)

  Changed paths:
    M clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
    M clang/test/Analysis/copy-elision.cpp
    M clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
    M clang/test/Analysis/loop-block-counts.c
    M clang/test/Analysis/stack-addr-ps.cpp

  Log Message:
  -----------
  [analyzer] Catch leaking stack addresses via stack variables

Not only global variables can hold references to dead stack variables.
Consider this example:

  void write_stack_address_to(char **q) {
    char local;
    *q = &local;
  }

  void test_stack() {
    char *p;
    write_stack_address_to(&p);
  }

The address of 'local' is assigned to 'p', which becomes a dangling
pointer after 'write_stack_address_to()' returns.

The StackAddrEscapeChecker was looking for bindings in the store which
referred to variables of the popped stack frame, but it only considered
global variables in this regard. This patch relaxes this, catching
stack variable bindings as well.

---

This patch also works for temporary objects like:

  struct Bar {
    const int &ref;
    explicit Bar(int y) : ref(y) {
      // Okay.
    } // End of the constructor call, `ref` is dangling now. Warning!
  };

  void test() {
    Bar{33}; // Temporary object, so the corresponding memregion is
             // *not* a VarRegion.
  }

---

The return value optimization aka. copy-elision might kick in but that
is modeled by passing an imaginary CXXThisRegion which refers to the
parent stack frame which is supposed to be the 'return slot'.
Objects residing in the 'return slot' outlive the scope of the inner
call, thus we should expect no warning about them - except if we
explicitly disable copy-elision.

Reviewed By: NoQ, martong

Differential Revision: https://reviews.llvm.org/D107078




More information about the All-commits mailing list