From bd2405e2926a17057fd706ff2dd174ab95aa9e26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Thu, 13 Mar 2014 12:26:03 +0100
Subject: [PATCH] Fix crash when the model contains 1st or 2nd ext fcn deriv
 nodes.

In the case where the external function computes itself its derivatives, the
TEF terms were not always created before being used, hence leading to a
preprocessor crash. This problem could only happen with ramsey_policy, because
otherwise the model does not contain derivatives of external functions.
---
 ExprNode.cc | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/ExprNode.cc b/ExprNode.cc
index f435107a..d7f7bd4d 100644
--- a/ExprNode.cc
+++ b/ExprNode.cc
@@ -5018,7 +5018,17 @@ FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Exp
   int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id);
   assert(first_deriv_symb_id != eExtFunSetButNoNameProvided);
 
-  if (first_deriv_symb_id == symb_id || alreadyWrittenAsTefTerm(first_deriv_symb_id, tef_terms))
+  /* For a node with derivs provided by the user function, call the method
+     on the non-derived node */
+  if (first_deriv_symb_id == symb_id)
+    {
+      expr_t parent = datatree.AddExternalFunction(symb_id, arguments);
+      parent->writeExternalFunctionOutput(output, output_type, temporary_terms,
+                                          tef_terms);
+      return;
+    }
+
+  if (alreadyWrittenAsTefTerm(first_deriv_symb_id, tef_terms))
     return;
 
   if (IS_C(output_type))
@@ -5285,8 +5295,17 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex
   int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id);
   assert(second_deriv_symb_id != eExtFunSetButNoNameProvided);
 
-  if (alreadyWrittenAsTefTerm(second_deriv_symb_id, tef_terms)
-      || second_deriv_symb_id == symb_id)
+  /* For a node with derivs provided by the user function, call the method
+     on the non-derived node */
+  if (second_deriv_symb_id == symb_id)
+    {
+      expr_t parent = datatree.AddExternalFunction(symb_id, arguments);
+      parent->writeExternalFunctionOutput(output, output_type, temporary_terms,
+                                          tef_terms);
+      return;
+    }
+
+  if (alreadyWrittenAsTefTerm(second_deriv_symb_id, tef_terms))
     return;
 
   if (IS_C(output_type))
-- 
GitLab