<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 --- - Regression: Lambda with no return behaves differently from lambda with empty return"
   href="https://llvm.org/bugs/show_bug.cgi?id=24989">24989</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Regression: Lambda with no return behaves differently from lambda with empty return
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>3.7
          </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>C++14
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>kenton@sandstorm.io
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The code below worked in Clang 3.6 but fails to compile in 3.7. This in
particular is breaking some code that uses Cap'n Proto.

It appears Clang 3.7 treats "[]()(auto) {}" differently from "[]()(auto)
{return;}", even though they are clearly equivalent. In the former case, in
some scenarios (but not all), it fails to recognize that the return type is
"void".

==== TEST CASE ====

// compile with:
//   clang --std=c++14 -c test.cc

template <typename R, typename C, typename P>
void match(R (C::*p)(P) const) {}

template <typename Func>
void matchFunctor(Func&& func) {
  typedef decltype(func(1)) ReturnType;
  match<ReturnType, Func, int&&>(&Func::operator());
}

void f() {
  matchFunctor([](auto) {});          // ERROR in clang 3.7, works in 3.6-
  matchFunctor([](auto) {return;});   // works in all versions
}

=== OUTPUT ===

test.cc:10:3: error: no matching function for call to 'match'
  match<ReturnType, Func, int&&>(&Func::operator());
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cc:14:3: note: in instantiation of function template specialization
'matchFunctor<(lambda at test.cc:14:16)>' requested here
  matchFunctor([](auto) {});          // ERROR in clang 3.7, works in 3.6-
  ^
test.cc:5:6: note: candidate function [with R = void, C = (lambda at
test.cc:14:16), P = int &&] not viable: no overload of 'operator()' matching
      'void ((lambda at test.cc:14:16)::*)(int &&) const' for 1st argument
void match(R (C::*p)(P) const) {}
     ^
1 error generated.</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>