From b299983a8bcf5acf753a8aa38c4d27bad78e3767 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Wed, 14 Aug 2019 15:28:41 +0200
Subject: [PATCH] Fix the notmpterms option in the presence of external
 functions

---
 src/ModelTree.cc | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index cb5819bb..3f3d045c 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -1337,23 +1337,32 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms)
 
   // Compute the temporary terms in equations and derivatives
   map<pair<int, int>, temporary_terms_t> temp_terms_map;
-  if (!no_tmp_terms)
-    {
-      map<expr_t, pair<int, pair<int, int>>> reference_count;
+  map<expr_t, pair<int, pair<int, int>>> reference_count;
 
-      for (auto & equation : equations)
-        equation->computeTemporaryTerms({ 0, 0 },
-                                        temp_terms_map,
-                                        reference_count,
-                                        is_matlab);
-
-      for (int order = 1; order < static_cast<int>(derivatives.size()); order++)
-        for (const auto &it : derivatives[order])
-          it.second->computeTemporaryTerms({ 0, order },
-                                           temp_terms_map,
-                                           reference_count,
-                                           is_matlab);
-    }
+  for (auto & equation : equations)
+    equation->computeTemporaryTerms({ 0, 0 },
+                                    temp_terms_map,
+                                    reference_count,
+                                    is_matlab);
+
+  for (int order = 1; order < static_cast<int>(derivatives.size()); order++)
+    for (const auto &it : derivatives[order])
+      it.second->computeTemporaryTerms({ 0, order },
+                                       temp_terms_map,
+                                       reference_count,
+                                       is_matlab);
+
+  /* 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 : temp_terms_map)
+      // The following loop can be simplified with std::erase_if() in C++20
+      for (auto it2 = it.second.begin(); it2 != it.second.end(); )
+        if (!dynamic_cast<AbstractExternalFunctionNode *>(*it2))
+          it2 = it.second.erase(it2);
+        else
+          ++it2;
 
   // Fill the (now obsolete) temporary_terms structure
   temporary_terms.clear();
-- 
GitLab