diff --git a/compiler2/record.c b/compiler2/record.c
index 1d54fe78e031dab32a5dfeca50efd1520ac5ed9b..b1ed521832c1fffd686f1179d908e16878e752ca 100644
--- a/compiler2/record.c
+++ b/compiler2/record.c
@@ -8162,6 +8162,15 @@ void defRecordTemplate2(const struct_def *sdef, output_struct *output)
     def = mputprintf(def, "%s_template(const %s_template& other_value): %s() "
       "{ copy_template(other_value); }\n", name, name, base_class);
 
+    /* destructor */
+    def = mputprintf(def, "~%s_template();\n", name);
+    src = mputprintf(src, "%s_template::~%s_template()\n"
+      "{\n"
+      "if (template_selection == DYNAMIC_MATCH && dyn_match->ref_count == 1) {\n"
+      "delete (static_cast<Dynamic_Match_Interface<%s>*>(dyn_match->ptr));\n"
+      "}\n"
+      "}\n\n", name, name, name);
+
     /* matching function for dynamic templates */
     def = mputstr(def, "boolean match_dynamic(const Base_Type* match_value) const;\n");
     src = mputprintf(src,
@@ -8169,7 +8178,7 @@ void defRecordTemplate2(const struct_def *sdef, output_struct *output)
       "{\n"
       "const %s* actual_value = dynamic_cast<const %s*>(match_value);\n"
       "return (static_cast<Dynamic_Match_Interface<%s>*>(dyn_match->ptr))->match(*actual_value);\n"
-      "}\n", name, name, name, name);
+      "}\n\n", name, name, name, name);
 
     /* assignment operator <- template_sel */
     def = mputprintf(def, "%s_template& operator=(template_sel other_value);\n",
diff --git a/compiler2/record_of.c b/compiler2/record_of.c
index 7d37b15193b36843cdc1336c54ba807130d6799b..68b6978f39ea2ee6ca4f76a54db953278163c5b3 100644
--- a/compiler2/record_of.c
+++ b/compiler2/record_of.c
@@ -4854,6 +4854,15 @@ void defRecordOfTemplate2(const struct_of_def *sdef, output_struct *output)
   def = mputprintf(def, "%s_template(const %s_template& other_value): %s() { copy_template(other_value); }\n",
                    name, name, base_class);
 
+  /* destructor */
+  def = mputprintf(def, "~%s_template();\n", name);
+  src = mputprintf(src, "%s_template::~%s_template()\n"
+    "{\n"
+    "if (template_selection == DYNAMIC_MATCH && dyn_match->ref_count == 1) {\n"
+    "delete (static_cast<Dynamic_Match_Interface<%s>*>(dyn_match->ptr));\n"
+    "}\n"
+    "}\n\n", name, name, name);
+
   /* matching function for dynamic templates */
   def = mputstr(def, "boolean match_dynamic(const Base_Type* match_value) const;\n");
   src = mputprintf(src,
diff --git a/core/Template.cc b/core/Template.cc
index 9ee550f5d263bd9dcc4a567d1c631ac3c890668d..6e2fffa98a8906ad964c71fe7031f3a11d7a3419 100644
--- a/core/Template.cc
+++ b/core/Template.cc
@@ -623,7 +623,6 @@ void Record_Of_Template::clean_up()
   case DYNAMIC_MATCH:
     dyn_match->ref_count--;
     if (dyn_match->ref_count == 0) {
-      delete dyn_match->ptr;
       delete dyn_match;
     }
     break;
@@ -1741,7 +1740,6 @@ void Set_Of_Template::clean_up()
   case DYNAMIC_MATCH:
     dyn_match->ref_count--;
     if (dyn_match->ref_count == 0) {
-      delete dyn_match->ptr;
       delete dyn_match;
     }
     break;
@@ -2763,7 +2761,6 @@ void Record_Template::clean_up()
   case DYNAMIC_MATCH:
     dyn_match->ref_count--;
     if (dyn_match->ref_count == 0) {
-      delete dyn_match->ptr;
       delete dyn_match;
     }
     break;
@@ -3469,7 +3466,6 @@ void Empty_Record_Template::clean_up()
   case DYNAMIC_MATCH:
     dyn_match->ref_count--;
     if (dyn_match->ref_count == 0) {
-      delete dyn_match->ptr;
       delete dyn_match;
     }
     break;