<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - Implicitly converts lvalue to rvalue when returning reference parameter in function template"
   href="https://llvm.org/bugs/show_bug.cgi?id=23440">23440</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Implicitly converts lvalue to rvalue when returning reference parameter in function template
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>3.5
          </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>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Frontend
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>david@doublewise.net
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>#include <type_traits>

template<typename T>
auto compiles(T && t) -> T && {
    static_assert(std::is_same<T, int>::value, "Incorrect type deduced for
T.");
    return t;
}
static_assert(std::is_same<int &&, decltype(compiles(0))>::value, "shouldn't
compile");

auto fails(int && t) -> int && {
    return t;
}
static_assert(std::is_same<int &&, decltype(fails(0))>::value, "doesn't
compile");


Neither function should compile. In the function template case, T is deduced as
int, so the parameter type is int &&. Local variables and function parameters
taken by value can be implicitly moved into the return value, but not function
parameters taken by rvalue reference (t is an lvalue, even though decltype(t)
== int &&).

The non-template function correctly honors this behavior.

If the return type of compiles is changed to decltype(auto) or auto &&, then
the function correctly returns int & and the static_assert fires.</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>