From fe83933b1d0ecbd06a6b7c0437471d0b99b8d16e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Thu, 2 Mar 2023 15:55:51 +0100 Subject: [PATCH] Bugfix: undefined behaviour in AbstractExternalFunctionNode::prepareForDerivation() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Input and output ranges should not overlap when calling std::set_union(), otherwise the behaviour is undefined. It seems that in this precise case the computation would still be correct (though inefficient), because of the properties of std::set or because of the specific implementation in libstdc++. But it’s better to be on the safe side. --- src/ExprNode.cc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 09f40905..81ba65f4 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -6758,11 +6758,15 @@ AbstractExternalFunctionNode::prepareForDerivation() non_null_derivatives = arguments.at(0)->non_null_derivatives; for (int i = 1; i < static_cast<int>(arguments.size()); i++) - set_union(non_null_derivatives.begin(), - non_null_derivatives.end(), - arguments.at(i)->non_null_derivatives.begin(), - arguments.at(i)->non_null_derivatives.end(), - inserter(non_null_derivatives, non_null_derivatives.begin())); + { + set<int> non_null_derivatives_tmp; + set_union(non_null_derivatives.begin(), + non_null_derivatives.end(), + arguments.at(i)->non_null_derivatives.begin(), + arguments.at(i)->non_null_derivatives.end(), + inserter(non_null_derivatives_tmp, non_null_derivatives_tmp.begin())); + non_null_derivatives = move(non_null_derivatives_tmp); + } preparedForDerivation = true; } -- GitLab