From c92817ce8d63df3e3c7225d77723f1c4ae725f58 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 18 Aug 2010 19:02:34 +0000 Subject: [PATCH] gdb PR symtab/11919: * gdbtypes.c (lookup_struct_elt_type): Clean up error emission. * parse.c (parse_field_expression): Use RETURN_MASK_ERROR. Move name-copying lower. Document exception behavior. * completer.c (expression_completer): Catch exceptions from parse_field_expression. gdb/testsuite PR symtab/11919: * gdb.base/completion.exp: Add test. --- gdb/ChangeLog | 9 +++++++++ gdb/completer.c | 11 +++++++++-- gdb/gdbtypes.c | 20 +++++++------------- gdb/parse.c | 14 +++++++++----- gdb/testsuite/ChangeLog | 5 +++++ gdb/testsuite/gdb.base/completion.exp | 19 ++----------------- 6 files changed, 41 insertions(+), 37 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d69d6c5..5ae1bc6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2010-08-18 Tom Tromey + + PR symtab/11919: + * gdbtypes.c (lookup_struct_elt_type): Clean up error emission. + * parse.c (parse_field_expression): Use RETURN_MASK_ERROR. Move + name-copying lower. Document exception behavior. + * completer.c (expression_completer): Catch exceptions from + parse_field_expression. + 2010-08-18 Pedro Alves PR corefile/8210 diff --git a/gdb/completer.c b/gdb/completer.c index 3ba481e..91b899d 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -24,6 +24,7 @@ #include "filenames.h" /* For DOSish file names. */ #include "language.h" #include "gdb_assert.h" +#include "exceptions.h" #include "cli/cli-decode.h" @@ -414,13 +415,19 @@ add_struct_fields (struct type *type, int *nextp, char **output, char ** expression_completer (struct cmd_list_element *ignore, char *text, char *word) { - struct type *type; + struct type *type = NULL; char *fieldname, *p; + volatile struct gdb_exception except; /* Perform a tentative parse of the expression, to see whether a field completion is required. */ fieldname = NULL; - type = parse_field_expression (text, &fieldname); + TRY_CATCH (except, RETURN_MASK_ERROR) + { + type = parse_field_expression (text, &fieldname); + } + if (except.reason < 0) + return NULL; if (fieldname && type) { for (;;) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index da4d673..c35adbb 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1212,6 +1212,7 @@ struct type * lookup_struct_elt_type (struct type *type, char *name, int noerr) { int i; + char *typename; for (;;) { @@ -1225,11 +1226,9 @@ lookup_struct_elt_type (struct type *type, char *name, int noerr) if (TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_UNION) { - target_terminal_ours (); - gdb_flush (gdb_stdout); - fprintf_unfiltered (gdb_stderr, "Type "); - type_print (type, "", gdb_stderr, -1); - error (_(" is not a structure or union type.")); + typename = type_to_string (type); + make_cleanup (xfree, typename); + error (_("Type %s is not a structure or union type."), typename); } #if 0 @@ -1281,14 +1280,9 @@ lookup_struct_elt_type (struct type *type, char *name, int noerr) return NULL; } - target_terminal_ours (); - gdb_flush (gdb_stdout); - fprintf_unfiltered (gdb_stderr, "Type "); - type_print (type, "", gdb_stderr, -1); - fprintf_unfiltered (gdb_stderr, " has no component named "); - fputs_filtered (name, gdb_stderr); - error ((".")); - return (struct type *) -1; /* For lint */ + typename = type_to_string (type); + make_cleanup (xfree, typename); + error (_("Type %s has no component named %s."), typename, name); } /* Lookup the vptr basetype/fieldno values for TYPE. diff --git a/gdb/parse.c b/gdb/parse.c index c885c6a..035572e 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -1202,8 +1202,10 @@ parse_expression (char *string) /* Parse STRING as an expression. If parsing ends in the middle of a field reference, return the type of the left-hand-side of the reference; furthermore, if the parsing ends in the field name, - return the field name in *NAME. In all other cases, return NULL. - Returned non-NULL *NAME must be freed by the caller. */ + 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. */ struct type * parse_field_expression (char *string, char **name) @@ -1213,7 +1215,7 @@ parse_field_expression (char *string, char **name) int subexp; volatile struct gdb_exception except; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY_CATCH (except, RETURN_MASK_ERROR) { in_parse_field = 1; exp = parse_exp_in_context (&string, 0, 0, 0, &subexp); @@ -1233,10 +1235,12 @@ parse_field_expression (char *string, char **name) xfree (exp); return NULL; } - /* (*NAME) is a part of the EXP memory block freed below. */ - *name = xstrdup (*name); + /* This might throw an exception. If so, we want to let it + propagate. */ val = evaluate_subexpression_type (exp, subexp); + /* (*NAME) is a part of the EXP memory block freed below. */ + *name = xstrdup (*name); xfree (exp); return value_type (val); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 5490e7e..0cbb3ad4 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-08-18 Tom Tromey + + PR symtab/11919: + * gdb.base/completion.exp: Add test. + 2010-08-18 Doug Evans * gdb.base/call-ar-st.exp (set_lang_c): Delete, unused. diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp index 5c91631..1f7c214 100644 --- a/gdb/testsuite/gdb.base/completion.exp +++ b/gdb/testsuite/gdb.base/completion.exp @@ -827,23 +827,8 @@ gdb_expect { timeout { fail "(timeout) complete 'set follow-fork-mode'" } } -send_gdb "p values\[0\].nonex.\t" -gdb_expect { - -re "Type struct some_struct has no component named nonex.\r\n$gdb_prompt $"\ - { pass "Completing non-existing component" } - -re ".*$gdb_prompt $" { fail "Completing non-existing component" } - timeout { fail "(timeout) Completing non-existing component" } - eof { fail "(eof) Completing non-existing component #2" } - } -# Double memory freeing gets found only on the second run: -send_gdb "p values\[0\].nonex.\t" -gdb_expect { - -re "Type struct some_struct has no component named nonex.\r\n$gdb_prompt $"\ - { pass "Completing non-existing component #2" } - -re ".*$gdb_prompt $" { fail "Completing non-existing component #2" } - timeout { fail "(timeout) Completing non-existing component #2" } - eof { fail "(eof) Completing non-existing component #2" } - } +gdb_test_no_output "complete print values\[0\].x." \ + "field completion with invalid field" # If there is a non-deprecated completion, it should be returned. gdb_test "complete sav" "save" "test non-deprecated completion" -- 2.7.4