From bd9943a6952d52116d1f9ac9f01d2562f3e6815f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 1 Sep 2023 13:48:31 +0200
Subject: [PATCH] Bytecode: fix memory leak in Evaluate class

The newly-created FBEGINBLOCK_ and FCALL_ instances were freed using a
base-class pointer. But the latter does not have a virtual destructor.

Those class instances are now stored by value in containers, so that the
destructor of the derived class is used.
---
 mex/sources/bytecode/Evaluate.cc |  8 ++++----
 mex/sources/bytecode/Evaluate.hh | 11 ++++++++---
 preprocessor                     |  2 +-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/mex/sources/bytecode/Evaluate.cc b/mex/sources/bytecode/Evaluate.cc
index 8a7581622f..0fde22de0d 100644
--- a/mex/sources/bytecode/Evaluate.cc
+++ b/mex/sources/bytecode/Evaluate.cc
@@ -229,10 +229,10 @@ Evaluate::Evaluate(const filesystem::path &codfile, bool steady_state_arg, const
 # ifdef DEBUGL
           mexPrintf("FBEGINBLOCK\n");
 # endif
-          deserialized_special_instrs.push_back(make_unique<FBEGINBLOCK_>(code));
+          deserialized_fbeginblock.emplace_back(code);
           begin_block.push_back(instructions_list.size());
           nb_blocks++;
-          instr = deserialized_special_instrs.back().get();
+          instr = &deserialized_fbeginblock.back();
           break;
         case Tags::FJMPIFEVAL:
 # ifdef DEBUGL
@@ -250,8 +250,8 @@ Evaluate::Evaluate(const filesystem::path &codfile, bool steady_state_arg, const
 # ifdef DEBUGL
           mexPrintf("FCALL\n");
 # endif
-          deserialized_special_instrs.push_back(make_unique<FCALL_>(code));
-          instr = deserialized_special_instrs.back().get();
+          deserialized_fcall.emplace_back(code);
+          instr = &deserialized_fcall.back();
           break;
         case Tags::FLDTEF:
 # ifdef DEBUGL
diff --git a/mex/sources/bytecode/Evaluate.hh b/mex/sources/bytecode/Evaluate.hh
index dcb004d7c4..609f5512c8 100644
--- a/mex/sources/bytecode/Evaluate.hh
+++ b/mex/sources/bytecode/Evaluate.hh
@@ -26,6 +26,7 @@
 #include <optional>
 #include <memory>
 #include <filesystem>
+#include <deque>
 
 #include "Bytecode.hh"
 #include "BasicSymbolTable.hh"
@@ -43,11 +44,15 @@ private:
   unique_ptr<char[]> raw_bytecode;
 
   /* Owns read instructions that have their specialized deserializing
-     constructors (and are thus not part of the “code” memory block) */
-  vector<unique_ptr<BytecodeInstruction>> deserialized_special_instrs;
+     constructors (and are thus not part of the “code” memory block). We use
+     std::deque for storing them, because that class guarantees the stability
+     of iterators, and thus of pointers to elements; we store such pointers in
+     the “instructions_list” data member. */
+  deque<FBEGINBLOCK_> deserialized_fbeginblock;
+  deque<FCALL_> deserialized_fcall;
 
   /* List of deserialized instructions
-     Those are either pointers inside “raw_bytecode” or “deserialized_special_instrs” */
+     Those are either pointers inside “raw_bytecode” or “deserialized_{fbeginblock,fcall}” */
   instructions_list_t instructions_list;
 
    // Number of blocks in the model
diff --git a/preprocessor b/preprocessor
index 92f42bdf68..3a18707685 160000
--- a/preprocessor
+++ b/preprocessor
@@ -1 +1 @@
-Subproject commit 92f42bdf68bbdb217647e5268dc91cc7cf05df87
+Subproject commit 3a187076859751ebc3f6a4e43c9ffc3149655191
-- 
GitLab