eval.c:evaluate_subexp_standard: Use RAII to avoid leaks

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-20  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'.
This commit is contained in:
Pedro Alves 2017-09-21 00:34:41 +01:00
parent ca464aac1b
commit c83833f493
2 changed files with 35 additions and 14 deletions

View file

@ -1,3 +1,10 @@
2017-09-20 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'.
2017-09-20 Tom Tromey <tom@tromey.com> 2017-09-20 Tom Tromey <tom@tromey.com>
* windows-nat.c (get_windows_debug_event, windows_wait) * windows-nat.c (get_windows_debug_event, windows_wait)

View file

@ -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 /* Represents a fake method with the given parameter types. This is
function is used by the parser to construct an "expected" type for used by the parser to construct a temporary "expected" type for
method overload resolution. FLAGS is used as instance flags of the 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 new type, in order to be able to make the new type represent a
const/volatile overload. */ const/volatile overload. */
static struct type * class fake_method
make_params (type_instance_flags flags,
int num_types, struct type **param_types)
{ {
struct type *type = XCNEW (struct type); public:
TYPE_MAIN_TYPE (type) = XCNEW (struct main_type); 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_LENGTH (type) = 1;
TYPE_CODE (type) = TYPE_CODE_METHOD; TYPE_CODE (type) = TYPE_CODE_METHOD;
TYPE_CHAIN (type) = type; TYPE_CHAIN (type) = type;
@ -681,8 +696,11 @@ make_params (type_instance_flags flags,
while (num_types-- > 0) while (num_types-- > 0)
TYPE_FIELD_TYPE (type, num_types) = param_types[num_types]; 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. */ /* Helper for evaluating an OP_VAR_VALUE. */
@ -2076,13 +2094,9 @@ evaluate_subexp_standard (struct type *expect_type,
for (ix = 0; ix < nargs; ++ix) for (ix = 0; ix < nargs; ++ix)
arg_types[ix] = exp->elts[pc + 2 + ix + 1].type; 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; *(pos) += 4 + nargs;
arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside); return evaluate_subexp_standard (expect_type.type (), exp, pos, noside);
xfree (TYPE_FIELDS (expect_type));
xfree (TYPE_MAIN_TYPE (expect_type));
xfree (expect_type);
return arg1;
} }
case BINOP_CONCAT: case BINOP_CONCAT: