<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - StackAddressEscape doesn't properly lifetime extend temporaries bound to static variables"
   href="https://bugs.llvm.org/show_bug.cgi?id=37547">37547</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>StackAddressEscape doesn't properly lifetime extend temporaries bound to static variables
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Static Analyzer
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>dcoughlin@apple.com
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>george.burgess.iv@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Test-case:

$ cat /tmp/f.cpp
struct Foo {
  Foo();
  ~Foo();                                                                       
  int i;
};

const void *foo() {
  static const Foo &f = {};
  return &f;
}

$ clang-tidy -checks=clang-analyzer-core.StackAddressEscape /tmp/f.cpp --
2 warnings generated.
/tmp/f.cpp:9:3: warning: Address of stack memory associated with temporary
object of type 'Foo' returned to caller
[clang-analyzer-core.StackAddressEscape]
  return &f;
  ^
/tmp/f.cpp:9:3: note: Address of stack memory associated with temporary object
of type 'Foo' returned to caller
/tmp/f.cpp:10:1: warning: Address of stack memory associated with temporary
object of type 'Foo' is still referred to by the static variable 'f' upon
returning to the caller.  This will be a dangling reference
[clang-analyzer-core.StackAddressEscape]
}
^
/tmp/f.cpp:10:1: note: Address of stack memory associated with temporary object
of type 'Foo' is still referred to by the static variable 'f' upon returning to
the caller.  This will be a dangling reference


----------------

Reading the C++ standard, however, it appears that temporary lifetime extension
extends the lifetime of temporaries to live as long as the reference they're
being bound to. So, since `f` is static, the temporary being bound to it gets
to live until the program dies: <a href="https://godbolt.org/g/snsWA7">https://godbolt.org/g/snsWA7</a> (please note the
atexit dtor call and extra global `_ZGRZ3foovE1f_`)

For added fun, this appears to apply to struct fields, too:
<a href="https://godbolt.org/g/NdV7jW">https://godbolt.org/g/NdV7jW</a>

(FWIW, the struct fields example is a reduced version of how I found this. When
I first saw it, I thought the code was broken, too. :) )</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>