From dea9de79b7d508a9f5ac5d270d97f3b5e248056d Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Mon, 29 Aug 2016 07:36:28 -0400 Subject: [PATCH] callFunction: Copy functors to the heap Normally it's impossible to take a reference to the function passed to callFunction, so some callers (e.g. ExprApp::eval) allocate that value on the stack. For functors, a reference to the functor itself may be kept, so we need to have it on the heap. Fixes #1045 (cherry picked from commit 9fa21765e7f267efcc65e1aa6ab21402ea6125ad) --- src/libexpr/eval.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 3b21c078..78da6a14 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -946,11 +946,18 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po if (fun.type == tAttrs) { auto found = fun.attrs->find(sFunctor); if (found != fun.attrs->end()) { + /* fun may be allocated on the stack of the calling function, + * but for functors we may keep a reference, so heap-allocate + * a copy and use that instead. + */ + auto & fun2 = *allocValue(); + fun2 = fun; + /* !!! Should we use the attr pos here? */ forceValue(*found->value, pos); - Value * v2 = allocValue(); - callFunction(*found->value, fun, *v2, pos); - forceValue(*v2, pos); - return callFunction(*v2, arg, v, pos); + Value v2; + callFunction(*found->value, fun2, v2, pos); + forceValue(v2, pos); + return callFunction(v2, arg, v, pos); } }