• Yedidya Feldblum's avatar
    recursive function · 9adda7dd
    Yedidya Feldblum authored
    Summary:
    Check that recursion builds with specific versions of gcc. Fix failures with that version.
    
    Addresses these failures:
    
    ```
    In file included from folly/test/FunctionTest.cpp:17:
    folly/Function.h: In substitution of 'template<class ReturnType, class ... Args> template<class F, class R> using IfSafeResult = folly::detail::function::IfSafeResultImpl<R, ReturnType> [with F = folly::Function<RecFolly()>; R = RecFolly; ReturnType = RecFolly; Args = {}]':
    folly/Function.h:761:7:   required by substitution of 'template<class Signature, class> folly::Function<RecFolly()>::Function(folly::Function<F>&&) [with Signature = RecFolly(); <template-parameter-1-2> = <missing>]'
    folly/Function.h:293:40:   required by substitution of 'template<class From, class To, class> using IfSafeResultImpl = decltype ((void)(static_cast<To>(declval<From>()))) [with From = RecFolly; To = RecFolly; <template-parameter-1-3> = void]'
    folly/Function.h:363:9:   required by substitution of 'template<class ReturnType, class ... Args> template<class F, class R> using IfSafeResult = folly::detail::function::IfSafeResultImpl<R, ReturnType> [with F = folly::Function<RecFolly()>; R = RecFolly; ReturnType = RecFolly; Args = {}]'
    folly/Function.h:761:7:   required by substitution of 'template<class Signature, class> folly::Function<RecFolly()>::Function(folly::Function<F>&&) [with Signature = RecFolly(); <template-parameter-1-2> = <missing>]'
    folly/Function.h:293:40:   required by substitution of 'template<class From, class To, class> using IfSafeResultImpl = decltype ((void)(static_cast<To>(declval<From>()))) [with From = RecFolly; To = RecFolly; <template-parameter-1-3> = void]'
    folly/Function.h:363:9:   [ skipping 501 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
    folly/Function.h:363:9:   required by substitution of 'template<class ReturnType, class ... Args> template<class F, class R> using IfSafeResult = folly::detail::function::IfSafeResultImpl<R, ReturnType> [with F = folly::Function<RecFolly()>; R = RecFolly; ReturnType = RecFolly; Args = {}]'
    folly/Function.h:761:7:   required by substitution of 'template<class Signature, class> folly::Function<RecFolly()>::Function(folly::Function<F>&&) [with Signature = RecFolly(); <template-parameter-1-2> = <missing>]'
    folly/Function.h:293:40:   required by substitution of 'template<class From, class To, class> using IfSafeResultImpl = decltype ((void)(static_cast<To>(declval<From>()))) [with From = RecFolly; To = RecFolly; <template-parameter-1-3> = void]'
    folly/Function.h:363:9:   required by substitution of 'template<class ReturnType, class ... Args> template<class F, class R> using IfSafeResult = folly::detail::function::IfSafeResultImpl<R, ReturnType> [with F = folly::Function<RecFolly()>; R = RecFolly; ReturnType = RecFolly; Args = {}]'
    folly/Function.h:761:7:   required by substitution of 'template<class Signature, class> folly::Function<RecFolly()>::Function(folly::Function<F>&&) [with Signature = RecFolly(); <template-parameter-1-2> = <missing>]'
    folly/test/FunctionTest.cpp:212:54:   required from here
    folly/Function.h:363:9: fatal error: template instantiation depth exceeds maximum of 512 (use '-ftemplate-depth=' to increase the maximum)
      363 |   using IfSafeResult = IfSafeResultImpl<R, ReturnType>;
          |         ^~~~~~~~~~~~
    compilation terminated.
    ```
    
    ```
    In file included from folly/test/FunctionTest.cpp:17:
    folly/Function.h: In member function 'virtual void Function_SelfMove_Test::TestBody()':
    folly/Function.h:709:70: error: 'f.folly::Function<int()>::exec_' is used uninitialized in this function [-Werror=uninitialized]
      709 |   Function(Function&& that) noexcept : call_(that.call_), exec_(that.exec_) {
          |                                                                 ~~~~~^~~~~
    folly/Function.h: In member function 'virtual void Function_SelfMove2_Test::TestBody()':
    folly/Function.h:709:70: warning: 'f.folly::Function<int()>::exec_' may be used uninitialized in this function [-Wmaybe-uninitialized]
      709 |   Function(Function&& that) noexcept : call_(that.call_), exec_(that.exec_) {
          |                                                                 ~~~~~^~~~~
    folly/Function.h: In member function 'virtual void Function_SelfStdSwap_Test::TestBody()':
    folly/Function.h:709:70: error: 'f.folly::Function<int()>::exec_' is used uninitialized in this function [-Werror=uninitialized]
      709 |   Function(Function&& that) noexcept : call_(that.call_), exec_(that.exec_) {
          |                                                                 ~~~~~^~~~~
    folly/Function.h:709:70: warning: 'f.folly::Function<int()>::exec_' may be used uninitialized in this function [-Wmaybe-uninitialized]
      709 |   Function(Function&& that) noexcept : call_(that.call_), exec_(that.exec_) {
          |                                                                 ~~~~~^~~~~
    folly/Function.h:709:70: warning: 'f.folly::Function<int()>::exec_' may be used uninitialized in this function [-Wmaybe-uninitialized]
      709 |   Function(Function&& that) noexcept : call_(that.call_), exec_(that.exec_) {
          |                                                                 ~~~~~^~~~~
    ```
    
    Notes:
    * For some versions of gcc, the compiler sees the converting-move-ctor as a better match than the actual move-ctor and this leads the compiler to infinite recursion; to work around this, explicitly exclude the same-type case of the converting-move-ctor.
    * `std::exchange` on `exec_` would be incorrect for self-move because of order of operations.
    * `std::exchange` on `call_` might be correct but it would be an extra template instantiation which is not desireable for `folly::Function`.
    
    Differential Revision: D33881266
    
    fbshipit-source-id: 5403b83498b9c1afa772564246eba4f112495761
    9adda7dd
FunctionTest.cpp 34.3 KB