<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 - [Diagnostic request] Lifetime of temporaries in range-based for loop"
   href="https://bugs.llvm.org/show_bug.cgi?id=32299">32299</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[Diagnostic request] Lifetime of temporaries in range-based for loop
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </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>C++11
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>bballo@mozilla.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Core Issue #1498 [1] / EWG Issue #120 [2] concerns the treatment of temporaries
in the range expression of a range-based for loop.

An example, taken from the EWG issue, is:

  std::vector<int> vec;
  for (int val : vec | boost::adaptors::reversed
                     | boost::adaptors::uniqued) {
    // Do stuff with val
  }

Here, while the temporary

  vec | boost::adaptors::reversed
      | boost::adaptors::uniqued

has its lifetime extended by the reference it's bound to (specified in the
lowering of the range-based for loop), the intermediate temporary

  vec | boost::adaptors::reversed

does not, resulting in references to it inside the retained temporary becoming
dangling, and the code exhibiting undefined behaviour.

One of the proposed resolutions for this issue is to extend the lifetimes of
all temporaries that appear in the range expression for the duration of the
loop.

While there has been no consensus for this (or any other) resolution so far,
the issue was discussed at the recent WG21 meeting in Kona, and Chandler
Carruth suggested that clang could be helpful and issue a diagnostic in cases
where it _would_ extend the lifetime of additional temporaries if the
resolution were adopted, to warn users about the potential lifetime error.

I would like to request that such a diagnostic be implemented. I believe that
the current behaviour (silent lifetime error leading to undefined behaviour) is
a significant "gotcha" for users of range-based for loops, and a diagnostic
along these lines would be very helpful.

[1] <a href="http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1498">http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1498</a>
[2] <a href="http://cplusplus.github.io/EWG/ewg-active.html#120">http://cplusplus.github.io/EWG/ewg-active.html#120</a></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>