From 5b80a4db590a68cba59529f6b46e101ad355b04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Wed, 8 Jul 2020 12:13:35 +0200 Subject: [PATCH] Unary ops substitution: bugfix, actually restrict the substitution to the chosen equations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default, the preprocessor is supposed to only do the “unary ops” transformation in the equations of VAR/PAC/trend component models. However, the implementation was slightly different so far. It would detect candidates to this transformation in the chosen equations, but it would then perform the substitution in *all* equations. This could lead for crashes, for example if the chosen equation contains log(X(-1)), but another (non-chosen) equation has log(X(-2)). Then this latter expression, even though it belongs to the same lag-equivalence class, is not properly handled, causing a segfault. Also do a few related cosmetic changes. --- src/DynamicModel.cc | 15 +++++++-------- src/ExprNode.cc | 4 +++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index e100f5e4..9b288c7a 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -5677,9 +5677,8 @@ DynamicModel::substituteUnaryOps(const vector<int> &eqnumbers) set<int> used_local_vars; for (int eqnumber : eqnumbers) equations[eqnumber]->collectVariables(SymbolType::modelLocalVariable, used_local_vars); - for (auto &it : local_variables_table) - if (used_local_vars.find(it.first) != used_local_vars.end()) - it.second->findUnaryOpNodesForAuxVarCreation(nodes); + for (int mlv : used_local_vars) + local_variables_table[mlv]->findUnaryOpNodesForAuxVarCreation(nodes); // Mark unary ops to be substituted in selected equations for (int eqnumber : eqnumbers) @@ -5687,16 +5686,16 @@ DynamicModel::substituteUnaryOps(const vector<int> &eqnumbers) // Substitute in model local variables vector<BinaryOpNode *> neweqs; - for (auto &it : local_variables_table) - it.second = it.second->substituteUnaryOpNodes(nodes, subst_table, neweqs); + for (int mlv : used_local_vars) + local_variables_table[mlv] = local_variables_table[mlv]->substituteUnaryOpNodes(nodes, subst_table, neweqs); // Substitute in equations - for (auto &equation : equations) + for (int eq : eqnumbers) { - auto substeq = dynamic_cast<BinaryOpNode *>(equation-> + auto substeq = dynamic_cast<BinaryOpNode *>(equations[eq]-> substituteUnaryOpNodes(nodes, subst_table, neweqs)); assert(substeq); - equation = substeq; + equations[eq] = substeq; } // Add new equations diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 4d0ef751..a83bb6d2 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -3530,7 +3530,9 @@ UnaryOpNode::substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_ else subst_table[rit->second] = dynamic_cast<VariableNode *>(aux_var->decreaseLeadsLags(base_index - rit->first)); - return const_cast<VariableNode *>(subst_table.find(this)->second); + assert(subst_table.find(this) != subst_table.end()); + + return const_cast<VariableNode *>(subst_table.at(this)); } expr_t -- GitLab