recursive function
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
Showing
Please register or sign in to comment