Remove a cleanup from parse_expression_for_completion
authorTom Tromey <tom@tromey.com>
Fri, 16 Feb 2018 05:41:03 +0000 (22:41 -0700)
committerTom Tromey <tom@tromey.com>
Wed, 21 Feb 2018 16:09:45 +0000 (09:09 -0700)
This removes a cleanup from parse_expression_for_completion, by
changing various expression-completion functions to use
gdb::unique_xmalloc_ptry rather than explicit malloc+free.

Regression tested by the buildbot.

gdb/ChangeLog
2018-02-21  Tom Tromey  <tom@tromey.com>

* value.h: (extract_field_op): Update.
* eval.c (extract_field_op): Return a const char *.
* expression.h (parse_expression_for_completion): Update.
* completer.c (complete_expression): Update.
(add_struct_fields): Make fieldname const.
* parse.c (expout_completion_name): Now a unique_xmalloc_ptr.
(mark_completion_tag, parse_exp_in_context_1): Update.
(parse_expression_for_completion): Change "name" to
unique_xmalloc_ptr*.

gdb/ChangeLog
gdb/completer.c
gdb/eval.c
gdb/expression.h
gdb/parse.c
gdb/value.h

index fae9db0651dbeb77d1e0fbc0aad889ab1e197181..a137560c1b800651c5f2a1643beac12ad71dbdd9 100644 (file)
@@ -1,3 +1,15 @@
+2018-02-21  Tom Tromey  <tom@tromey.com>
+
+       * value.h: (extract_field_op): Update.
+       * eval.c (extract_field_op): Return a const char *.
+       * expression.h (parse_expression_for_completion): Update.
+       * completer.c (complete_expression): Update.
+       (add_struct_fields): Make fieldname const.
+       * parse.c (expout_completion_name): Now a unique_xmalloc_ptr.
+       (mark_completion_tag, parse_exp_in_context_1): Update.
+       (parse_expression_for_completion): Change "name" to
+       unique_xmalloc_ptr*.
+
 2018-02-21  Tom Tromey  <tom@tromey.com>
 
        * infcall.c (call_function_by_hand_dummy): Use std::vector.
index a71bd368ff260c2658efa02f869742339f71b790..4de1bcff3295dac81266b0b8176cf8362b19f96c 100644 (file)
@@ -962,7 +962,7 @@ location_completer_handle_brkchars (struct cmd_list_element *ignore,
 
 static void
 add_struct_fields (struct type *type, completion_list &output,
-                  char *fieldname, int namelen)
+                  const char *fieldname, int namelen)
 {
   int i;
   int computed_type_name = 0;
@@ -1016,12 +1016,11 @@ complete_expression (completion_tracker &tracker,
                     const char *text, const char *word)
 {
   struct type *type = NULL;
-  char *fieldname;
+  gdb::unique_xmalloc_ptr<char> fieldname;
   enum type_code code = TYPE_CODE_UNDEF;
 
   /* Perform a tentative parse of the expression, to see whether a
      field completion is required.  */
-  fieldname = NULL;
   TRY
     {
       type = parse_expression_for_completion (text, &fieldname, &code);
@@ -1032,7 +1031,7 @@ complete_expression (completion_tracker &tracker,
     }
   END_CATCH
 
-  if (fieldname && type)
+  if (fieldname != nullptr && type)
     {
       for (;;)
        {
@@ -1045,25 +1044,20 @@ complete_expression (completion_tracker &tracker,
       if (TYPE_CODE (type) == TYPE_CODE_UNION
          || TYPE_CODE (type) == TYPE_CODE_STRUCT)
        {
-         int flen = strlen (fieldname);
          completion_list result;
 
-         add_struct_fields (type, result, fieldname, flen);
-         xfree (fieldname);
+         add_struct_fields (type, result, fieldname.get (),
+                            strlen (fieldname.get ()));
          tracker.add_completions (std::move (result));
          return;
        }
     }
-  else if (fieldname && code != TYPE_CODE_UNDEF)
+  else if (fieldname != nullptr && code != TYPE_CODE_UNDEF)
     {
-      struct cleanup *cleanup = make_cleanup (xfree, fieldname);
-
-      collect_symbol_completion_matches_type (tracker, fieldname, fieldname,
-                                             code);
-      do_cleanups (cleanup);
+      collect_symbol_completion_matches_type (tracker, fieldname.get (),
+                                             fieldname.get (), code);
       return;
     }
-  xfree (fieldname);
 
   complete_files_symbols (tracker, text, word);
 }
index 6f74c41b9f3a6268cd5606e1be7fb804d354af89..4899011a58ffd9afdb6424299ed9bef749724b85 100644 (file)
@@ -272,7 +272,7 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp,
    subexpression of the left-hand-side of the dereference.  This is
    used when completing field names.  */
 
-char *
+const char *
 extract_field_op (struct expression *exp, int *subexp)
 {
   int tem;
index 030f2f08e7ae6440a844f69895bd87a40bf284fe..7abd7f7503cf7dab6f2ccd9f9172da60d9e43247 100644 (file)
@@ -101,8 +101,8 @@ extern expression_up parse_expression (const char *);
 extern expression_up parse_expression_with_language (const char *string,
                                                     enum language lang);
 
-extern struct type *parse_expression_for_completion (const char *, char **,
-                                                    enum type_code *);
+extern struct type *parse_expression_for_completion
+    (const char *, gdb::unique_xmalloc_ptr<char> *, enum type_code *);
 
 extern expression_up parse_exp_1 (const char **, CORE_ADDR pc,
                                  const struct block *, int);
index e3f1306a175abd20e926ca9a34ef43e0e8f32b35..3abb9d421911829f06c48bbcb95e64ba51ce67f8 100644 (file)
@@ -88,7 +88,7 @@ static int expout_last_struct = -1;
 static enum type_code expout_tag_completion_type = TYPE_CODE_UNDEF;
 
 /* The token for tagged type name completion.  */
-static char *expout_completion_name;
+static gdb::unique_xmalloc_ptr<char> expout_completion_name;
 
 \f
 static unsigned int expressiondebug = 0;
@@ -575,9 +575,7 @@ mark_completion_tag (enum type_code tag, const char *ptr, int length)
              || tag == TYPE_CODE_STRUCT
              || tag == TYPE_CODE_ENUM);
   expout_tag_completion_type = tag;
-  expout_completion_name = (char *) xmalloc (length + 1);
-  memcpy (expout_completion_name, ptr, length);
-  expout_completion_name[length] = '\0';
+  expout_completion_name.reset (xstrndup (ptr, length));
 }
 
 \f
@@ -1137,8 +1135,7 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
   type_stack.depth = 0;
   expout_last_struct = -1;
   expout_tag_completion_type = TYPE_CODE_UNDEF;
-  xfree (expout_completion_name);
-  expout_completion_name = NULL;
+  expout_completion_name.reset ();
 
   comma_terminates = comma;
 
@@ -1277,11 +1274,11 @@ parse_expression_with_language (const char *string, enum language lang)
    reference; furthermore, if the parsing ends in the field name,
    return the field name in *NAME.  If the parsing ends in the middle
    of a field reference, but the reference is somehow invalid, throw
-   an exception.  In all other cases, return NULL.  Returned non-NULL
-   *NAME must be freed by the caller.  */
+   an exception.  In all other cases, return NULL.  */
 
 struct type *
-parse_expression_for_completion (const char *string, char **name,
+parse_expression_for_completion (const char *string,
+                                gdb::unique_xmalloc_ptr<char> *name,
                                 enum type_code *code)
 {
   expression_up exp;
@@ -1306,23 +1303,24 @@ parse_expression_for_completion (const char *string, char **name,
   if (expout_tag_completion_type != TYPE_CODE_UNDEF)
     {
       *code = expout_tag_completion_type;
-      *name = expout_completion_name;
-      expout_completion_name = NULL;
+      *name = std::move (expout_completion_name);
       return NULL;
     }
 
   if (expout_last_struct == -1)
     return NULL;
 
-  *name = extract_field_op (exp.get (), &subexp);
-  if (!*name)
-    return NULL;
+  const char *fieldname = extract_field_op (exp.get (), &subexp);
+  if (fieldname == NULL)
+    {
+      name->reset ();
+      return NULL;
+    }
 
+  name->reset (xstrdup (fieldname));
   /* This might throw an exception.  If so, we want to let it
      propagate.  */
   val = evaluate_subexpression_type (exp.get (), subexp);
-  /* (*NAME) is a part of the EXP memory block freed below.  */
-  *name = xstrdup (*name);
 
   return value_type (val);
 }
index e0ea22d4e52f98a25a950d1c72ec5006a80ad1fd..5676d245b94477943ba260d23881a4a095192e83 100644 (file)
@@ -889,7 +889,7 @@ extern void fetch_subexp_value (struct expression *exp, int *pc,
                                struct value **val_chain,
                                int preserve_errors);
 
-extern char *extract_field_op (struct expression *exp, int *subexp);
+extern const char *extract_field_op (struct expression *exp, int *subexp);
 
 extern struct value *evaluate_subexp_with_coercion (struct expression *,
                                                    int *, enum noside);