eval.c:evaluate_subexp_standard: Use RAII to avoid leaks

Message ID 1504554335-22534-1-git-send-email-palves@redhat.com
State New, archived
Headers

Commit Message

Pedro Alves Sept. 4, 2017, 7:45 p.m. UTC
  While working on the no-debug-info debugging improvements series, I
noticed these bare xfree calls, which lead to leaks if
evaluate_subexp_standard throws.

Fix that by reworking make_params as a RAII class.  Ends up
eliminating a couple heap allocations too.

gdb/ChangeLog:
2017-09-04  Pedro Alves  <palves@redhat.com>

	* eval.c (make_params): Delete, refactored as ...
	(class fake_method): ... this new type's ctor.
	(fake_method::~fake_method): New.
	(evaluate_subexp_standard): Use 'fake_method'.
---
 gdb/eval.c | 42 ++++++++++++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 14 deletions(-)
  

Comments

Pedro Alves Sept. 20, 2017, 11:37 p.m. UTC | #1
On 09/04/2017 08:45 PM, Pedro Alves wrote:
> While working on the no-debug-info debugging improvements series, I
> noticed these bare xfree calls, which lead to leaks if
> evaluate_subexp_standard throws.
> 
> Fix that by reworking make_params as a RAII class.  Ends up
> eliminating a couple heap allocations too.
> 
> gdb/ChangeLog:
> 2017-09-04  Pedro Alves  <palves@redhat.com>
> 
> 	* eval.c (make_params): Delete, refactored as ...
> 	(class fake_method): ... this new type's ctor.
> 	(fake_method::~fake_method): New.
> 	(evaluate_subexp_standard): Use 'fake_method'.

I'm pushing this in.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/eval.c b/gdb/eval.c
index 5a434b9..438b8a3 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -642,18 +642,33 @@  ptrmath_type_p (const struct language_defn *lang, struct type *type)
     }
 }
 
-/* Constructs a fake method with the given parameter types.  This
-   function is used by the parser to construct an "expected" type for
+/* Represents a fake method with the given parameter types.  This is
+   used by the parser to construct a temporary "expected" type for
    method overload resolution.  FLAGS is used as instance flags of the
    new type, in order to be able to make the new type represent a
    const/volatile overload.  */
 
-static struct type *
-make_params (type_instance_flags flags,
-	     int num_types, struct type **param_types)
+class fake_method
 {
-  struct type *type = XCNEW (struct type);
-  TYPE_MAIN_TYPE (type) = XCNEW (struct main_type);
+public:
+  fake_method (type_instance_flags flags,
+	       int num_types, struct type **param_types);
+  ~fake_method ();
+
+  /* The constructed type.  */
+  struct type *type () { return &m_type; }
+
+private:
+  struct type m_type {};
+  main_type m_main_type {};
+};
+
+fake_method::fake_method (type_instance_flags flags,
+			  int num_types, struct type **param_types)
+{
+  struct type *type = &m_type;
+
+  TYPE_MAIN_TYPE (type) = &m_main_type;
   TYPE_LENGTH (type) = 1;
   TYPE_CODE (type) = TYPE_CODE_METHOD;
   TYPE_CHAIN (type) = type;
@@ -681,8 +696,11 @@  make_params (type_instance_flags flags,
 
   while (num_types-- > 0)
     TYPE_FIELD_TYPE (type, num_types) = param_types[num_types];
+}
 
-  return type;
+fake_method::~fake_method ()
+{
+  xfree (TYPE_FIELDS (&m_type));
 }
 
 /* Helper for evaluating an OP_VAR_VALUE.  */
@@ -2051,13 +2069,9 @@  evaluate_subexp_standard (struct type *expect_type,
 	for (ix = 0; ix < nargs; ++ix)
 	  arg_types[ix] = exp->elts[pc + 2 + ix + 1].type;
 
-	expect_type = make_params (flags, nargs, arg_types);
+	fake_method expect_type (flags, nargs, arg_types);
 	*(pos) += 4 + nargs;
-	arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
-	xfree (TYPE_FIELDS (expect_type));
-	xfree (TYPE_MAIN_TYPE (expect_type));
-	xfree (expect_type);
-	return arg1;
+	return evaluate_subexp_standard (expect_type.type (), exp, pos, noside);
       }
 
     case BINOP_CONCAT: