From 3932196ff452eabeae474cecaca78ca65354acf8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 4 Nov 2022 12:00:11 +0100
Subject: [PATCH] Fix segfault of notmpterms option with block decomposition

By the way, ensure that temporary terms associated to external functions are
not removed, since they are not optional.

(manually cherry picked from commit 836351565da5358ba983a63563632e6180e97a65)
---
 src/DynamicModel.cc |  3 +--
 src/ModelTree.cc    | 14 +++++++++++++-
 src/ModelTree.hh    |  2 +-
 src/StaticModel.cc  |  3 +--
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index ae94133f..6026e514 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -4410,8 +4410,7 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO
 
       computeBlockDynJacobianCols();
 
-      if (!no_tmp_terms)
-        computeBlockTemporaryTerms();
+      computeBlockTemporaryTerms(no_tmp_terms);
     }
   else
     {
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index f9842961..ee06d07d 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -999,7 +999,7 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms)
 }
 
 void
-ModelTree::computeBlockTemporaryTerms()
+ModelTree::computeBlockTemporaryTerms(bool no_tmp_terms)
 {
   int nb_blocks = blocks.size();
   blocks_temporary_terms.resize(nb_blocks);
@@ -1030,6 +1030,18 @@ ModelTree::computeBlockTemporaryTerms()
       additionalBlockTemporaryTerms(blk, blocks_temporary_terms, reference_count);
     }
 
+  /* If the user has specified the notmpterms option, clear all temporary
+     terms, except those that correspond to external functions (since they are
+     not optional) */
+  if (no_tmp_terms)
+    for (auto &it : blocks_temporary_terms)
+      for (auto &it2 : it)
+        for (auto it3 = it2.begin(); it3 != it2.end();)
+          if (!dynamic_cast<AbstractExternalFunctionNode *>(*it3))
+            it3 = it2.erase(it3);
+          else
+            ++it3;
+
   // Compute indices in the temporary terms vector
   int idx = 0;
   blocks_temporary_terms_idxs.clear();
diff --git a/src/ModelTree.hh b/src/ModelTree.hh
index 75e96026..0c54edf9 100644
--- a/src/ModelTree.hh
+++ b/src/ModelTree.hh
@@ -221,7 +221,7 @@ protected:
   //! Computes temporary terms (for all equations and derivatives)
   void computeTemporaryTerms(bool is_matlab, bool no_tmp_terms);
   //! Computes temporary terms per block
-  void computeBlockTemporaryTerms();
+  void computeBlockTemporaryTerms(bool no_tmp_terms);
   /* Add additional temporary terms for a given block. This method is called by
      computeBlockTemporaryTerms(). It does nothing by default, but is meant to
      be overriden by subclasses (actually by DynamicModel, who needs extra
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index 7adf0a45..9efbbcbc 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -1072,8 +1072,7 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co
 
       determineLinearBlocks();
 
-      if (!no_tmp_terms)
-        computeBlockTemporaryTerms();
+      computeBlockTemporaryTerms(no_tmp_terms);
     }
   else
     {
-- 
GitLab