This changes libcc1 to use the 'deleter' template in a few more
places.  The template and basic specializations are moved to a new
header, then some unmarshall functions are changed to use this code.
This change avoids the need to repeat cleanup code in the
unmarshallers.

libcc1/ChangeLog
2021-01-03  Tom Tromey  <t...@tromey.com>

        * rpc.hh (deleter): Move template and some specializations to
        deleter.hh.
        (argument_wrapper<const T *>): Use cc1_plugin::unique_ptr.
        * marshall.cc (cc1_plugin::unmarshall): Use
        cc1_plugin::unique_ptr.
        * marshall-cp.hh (deleter): New specializations.
        (unmarshall): Use cc1_plugin::unique_ptr.
        * deleter.hh: New file.
---
 libcc1/ChangeLog      | 11 ++++++
 libcc1/deleter.hh     | 53 +++++++++++++++++++++++++++++
 libcc1/marshall-cp.hh | 79 +++++++++++++++++++++++++------------------
 libcc1/marshall.cc    | 11 +++---
 libcc1/rpc.hh         | 62 ++-------------------------------
 5 files changed, 116 insertions(+), 100 deletions(-)
 create mode 100644 libcc1/deleter.hh

diff --git a/libcc1/deleter.hh b/libcc1/deleter.hh
new file mode 100644
index 00000000000..70553eef8f8
--- /dev/null
+++ b/libcc1/deleter.hh
@@ -0,0 +1,53 @@
+/* Deleter objects
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef CC1_PLUGIN_DELETER_HH
+#define CC1_PLUGIN_DELETER_HH
+
+#include <memory>
+
+namespace cc1_plugin
+{
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template<typename T> struct deleter;
+
+  template<>
+  struct deleter<char>
+  {
+    void operator() (char *s)
+    {
+      delete[] s;
+    }
+  };
+
+  template<>
+  struct deleter<gcc_type_array>
+  {
+    void operator() (gcc_type_array *p)
+    {
+      delete[] p->elements;
+      delete p;
+    }
+  };
+
+  template<typename T> using unique_ptr = std::unique_ptr<T, deleter<T>>;
+}
+
+#endif // CC1_PLUGIN_DELETER_HH
diff --git a/libcc1/marshall-cp.hh b/libcc1/marshall-cp.hh
index e921ab0d3a9..f3c1dbd43ea 100644
--- a/libcc1/marshall-cp.hh
+++ b/libcc1/marshall-cp.hh
@@ -22,9 +22,42 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "marshall.hh"
 #include "gcc-cp-interface.h"
+#include "deleter.hh"
 
 namespace cc1_plugin
 {
+  template<>
+  struct deleter<gcc_vbase_array>
+  {
+    void operator() (gcc_vbase_array *p)
+    {
+      delete[] p->flags;
+      delete[] p->elements;
+      delete p;
+    }
+  };
+
+  template<>
+  struct deleter<gcc_cp_template_args>
+  {
+    void operator() (gcc_cp_template_args *p)
+    {
+      delete[] p->elements;
+      delete[] p->kinds;
+      delete p;
+    }
+  };
+
+  template<>
+  struct deleter<gcc_cp_function_args>
+  {
+    void operator() (gcc_cp_function_args *p)
+    {
+      delete[] p->elements;
+      delete p;
+    }
+  };
+
   // Send a gcc_vbase_array marker followed by the array.
   status
   marshall (connection *conn, const gcc_vbase_array *a)
@@ -67,7 +100,7 @@ namespace cc1_plugin
        return OK;
       }
 
-    struct gcc_vbase_array *gva = new gcc_vbase_array;
+    cc1_plugin::unique_ptr<gcc_vbase_array> gva (new gcc_vbase_array {});
 
     gva->n_elements = len;
     gva->elements = new gcc_type[len];
@@ -75,25 +108,16 @@ namespace cc1_plugin
     if (!unmarshall_array_elmts (conn,
                                 len * sizeof (gva->elements[0]),
                                 gva->elements))
-      {
-       delete[] gva->elements;
-       delete gva;
-       return FAIL;
-      }
+      return FAIL;
 
     gva->flags = new enum gcc_cp_symbol_kind[len];
 
     if (!unmarshall_array_elmts (conn,
                                 len * sizeof (gva->flags[0]),
                                 gva->flags))
-      {
-       delete[] gva->flags;
-       delete[] gva->elements;
-       delete gva;
-       return FAIL;
-      }
+      return FAIL;
 
-    *result = gva;
+    *result = gva.release ();
     return OK;
   }
 
@@ -139,7 +163,8 @@ namespace cc1_plugin
        return OK;
       }
 
-    struct gcc_cp_template_args *gva = new gcc_cp_template_args;
+    cc1_plugin::unique_ptr<gcc_cp_template_args> gva
+      (new gcc_cp_template_args {});
 
     gva->n_elements = len;
     gva->kinds = new char[len];
@@ -147,25 +172,16 @@ namespace cc1_plugin
     if (!unmarshall_array_elmts (conn,
                                 len * sizeof (gva->kinds[0]),
                                 gva->kinds))
-      {
-       delete[] gva->kinds;
-       delete gva;
-       return FAIL;
-      }
+      return FAIL;
 
     gva->elements = new gcc_cp_template_arg[len];
 
     if (!unmarshall_array_elmts (conn,
                                 len * sizeof (gva->elements[0]),
                                 gva->elements))
-      {
-       delete[] gva->elements;
-       delete[] gva->kinds;
-       delete gva;
-       return FAIL;
-      }
+      return FAIL;
 
-    *result = gva;
+    *result = gva.release ();
     return OK;
   }
 
@@ -208,7 +224,8 @@ namespace cc1_plugin
        return OK;
       }
 
-    struct gcc_cp_function_args *gva = new gcc_cp_function_args;
+    cc1_plugin::unique_ptr<gcc_cp_function_args> gva
+      (new gcc_cp_function_args {});
 
     gva->n_elements = len;
     gva->elements = new gcc_expr[len];
@@ -216,13 +233,9 @@ namespace cc1_plugin
     if (!unmarshall_array_elmts (conn,
                                 len * sizeof (gva->elements[0]),
                                 gva->elements))
-      {
-       delete[] gva->elements;
-       delete gva;
-       return FAIL;
-      }
+      return FAIL;
 
-    *result = gva;
+    *result = gva.release ();
 
     return OK;
   }
diff --git a/libcc1/marshall.cc b/libcc1/marshall.cc
index 368418a8215..5d2d3428a53 100644
--- a/libcc1/marshall.cc
+++ b/libcc1/marshall.cc
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 #include <string.h>
 #include "marshall.hh"
 #include "connection.hh"
+#include "rpc.hh"
 
 cc1_plugin::status
 cc1_plugin::unmarshall_check (connection *conn, unsigned long long check)
@@ -175,7 +176,7 @@ cc1_plugin::unmarshall (connection *conn, gcc_type_array 
**result)
       return OK;
     }
 
-  gcc_type_array *gta = new gcc_type_array;
+  cc1_plugin::unique_ptr<gcc_type_array> gta (new gcc_type_array {});
 
   gta->n_elements = len;
   gta->elements = new gcc_type[len];
@@ -183,13 +184,9 @@ cc1_plugin::unmarshall (connection *conn, gcc_type_array 
**result)
   if (!unmarshall_array_elmts (conn,
                               len * sizeof (gta->elements[0]),
                               gta->elements))
-    {
-      delete[] gta->elements;
-      delete *result;
-      return FAIL;
-    }
+    return FAIL;
 
-  *result = gta;
+  *result = gta.release ();
 
   return OK;
 }
diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index 00f108d6dc9..f829e77682d 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -22,7 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "status.hh"
 #include "connection.hh"
-#include <memory>
+#include "deleter.hh"
 
 namespace cc1_plugin
 {
@@ -55,64 +55,6 @@ namespace cc1_plugin
     T m_object;
   };
 
-  // Any pointer type requires a deleter object that knows how to
-  // clean up.  These are used in multiple places.
-  template<typename T> struct deleter;
-
-  template<>
-  struct deleter<char>
-  {
-    void operator() (char *s)
-    {
-      delete[] s;
-    }
-  };
-
-  template<>
-  struct deleter<gcc_type_array>
-  {
-    void operator() (gcc_type_array *p)
-    {
-      delete[] p->elements;
-      delete p;
-    }
-  };
-
-#ifdef GCC_CP_INTERFACE_H
-  template<>
-  struct deleter<gcc_vbase_array>
-  {
-    void operator() (gcc_vbase_array *p)
-    {
-      delete[] p->flags;
-      delete[] p->elements;
-      delete p;
-    }
-  };
-
-  template<>
-  struct deleter<gcc_cp_template_args>
-  {
-    void operator() (gcc_cp_template_args *p)
-    {
-      delete[] p->elements;
-      delete[] p->kinds;
-      delete p;
-    }
-  };
-
-  template<>
-  struct deleter<gcc_cp_function_args>
-  {
-    void operator() (gcc_cp_function_args *p)
-    {
-      delete[] p->elements;
-      delete p;
-    }
-  };
-
-#endif // GCC_CP_INTERFACE_H
-
   // Specialization for any kind of pointer.
   template<typename T>
   class argument_wrapper<T *>
@@ -142,7 +84,7 @@ namespace cc1_plugin
 
   private:
 
-    std::unique_ptr<type, deleter<type>> m_object;
+    unique_ptr<type> m_object;
   };
 
   // There are two kinds of template functions here: "call" and
-- 
2.26.2

Reply via email to