From 0f237df286ecaf366e19601917bedaf6224929d0 Mon Sep 17 00:00:00 2001 From: Tom Tromey <tom@tromey.com> Date: Tue, 4 May 2021 15:26:58 -0600 Subject: [PATCH] libcc1: add more uses of 'deleter' 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 * 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/deleter.hh | 53 +++++++++++++++++++++++++++++ libcc1/marshall-cp.hh | 79 +++++++++++++++++++++++++------------------ libcc1/marshall.cc | 11 +++--- libcc1/rpc.hh | 62 ++------------------------------- 4 files changed, 105 insertions(+), 100 deletions(-) create mode 100644 libcc1/deleter.hh diff --git a/libcc1/deleter.hh b/libcc1/deleter.hh new file mode 100644 index 000000000000..70553eef8f8c --- /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 3d6ae4126aee..ec616e09d952 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 aac077e2d6cd..4a7a21f5cd1b 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 4e00d61ee98d..09cd7bdda616 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 -- GitLab