https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77825

            Bug ID: 77825
           Summary: return type deduction regression in 7.0
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: barry.revzin at gmail dot com
  Target Milestone: ---

Can't come up with a more reduced example, but consider this code that makes a
Y combinator version of factorial and calls it:

#include <type_traits>
#include <utility>

template <class F>
struct y_combinator {
    F f;

    template <class... Args>
    decltype(auto) operator()(Args&&... args) const
    {
        return f(*this, std::forward<Args>(args)...);
    }
};
template <class F>
y_combinator<std::decay_t<F>> make_y_combinator(F&& f) {
    return {std::forward<F>(f)};
}

int main() {
    auto factorial = make_y_combinator([](auto fact, int n) -> int {
        if (n == 0) return 1;
        else        return n * fact(n - 1);
    });
    factorial(5);
}

The code is well formed, operator() returns decltype(auto), but f is a lambda
that explicitly returns int. The code compiles in 4.9.3, 5.3, and 6.1, but
fails on trunk 7.0 with:

prog.cc: In instantiation of 'main()::<lambda(auto:1, int)> [with auto:1 =
y_combinator<main()::<lambda(auto:1, int)> >]':
prog.cc:11:52:   required from 'decltype(auto)
y_combinator<F>::operator()(Args&& ...) const [with Args = {int}; F =
main()::<lambda(auto:1, int)>]'
prog.cc:24:16:   required from here
prog.cc:22:36: error: use of 'decltype(auto) y_combinator<F>::operator()(Args&&
...) const [with Args = {int}; F = main()::<lambda(auto:1, int)>]' before
deduction of 'auto'
         else        return n * fact(n - 1);
                                ~~~~^~~~~~~

Reply via email to