Skip to content

Commit 1174b9f

Browse files
paulbissfacebook-github-bot
authored andcommitted
Fix indeterminate ordering in typesToValues() (#4)
Summary: X-link: hhvm/hhvm-staging#4 We depend on the evaluation order of the lambda passed to typesToValues() (in particular we depend on it being called for each element type in the tuple in the order in which they appear in the tuple). In C++ the order in which the values of function parameters are resolved is indeterminate: > In a function call, value computations and side effects of the initialization of every parameter are indeterminately sequenced with respect to value computations and side effects of any other parameter. https://en.cppreference.com/w/cpp/language/eval_order This diff changes `typesToValuesImpl` to use a recursive definition that should have a well-defined order. Reviewed By: ricklavoie, alexeyt Differential Revision: D40489955 fbshipit-source-id: 4342dde6eeda4c1002795e4f7dc2ee41c9879152
1 parent 47fe355 commit 1174b9f

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

hphp/util/extern-worker-detail.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,23 @@ template <typename T> struct Tag { using Type = T; };
299299
// for each type in that tuple. The callable is called with the tuple
300300
// index as the first parameter, and Tag<T> as the second (where T is
301301
// the type at that tuple index).
302-
template <typename Tuple, typename F, size_t... Is>
302+
template <typename Tuple, typename F, typename... Args>
303303
auto typesToValuesImpl(F&& f,
304-
std::index_sequence<Is...>) {
305-
return std::make_tuple(f(Is, Tag<std::tuple_element_t<Is, Tuple>>{})...);
304+
std::index_sequence<>,
305+
Args&&... args) {
306+
return std::make_tuple(std::forward<Args>(args)...);
307+
}
308+
309+
template <typename Tuple, typename F, typename... Args, size_t I, size_t... Is>
310+
auto typesToValuesImpl(F&& f,
311+
std::index_sequence<I, Is...>,
312+
Args&&... args) {
313+
return typesToValuesImpl<Tuple>(
314+
std::forward<F>(f),
315+
std::index_sequence<Is...>{},
316+
std::forward<Args>(args)...,
317+
f(I, Tag<std::tuple_element_t<I, Tuple>>{})
318+
);
306319
}
307320

308321
template <typename Tuple, typename F>

0 commit comments

Comments
 (0)