aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2010-08-18 19:02:34 +0000
committerTom Tromey <tromey@redhat.com>2010-08-18 19:02:34 +0000
commitc92817ce8d63df3e3c7225d77723f1c4ae725f58 (patch)
treee7c50f7d6f489add476f812346cb7006f0347146
parent55455f8927ff9d4703d844163ef51b6e26cdef9e (diff)
downloadgdb-c92817ce8d63df3e3c7225d77723f1c4ae725f58.zip
gdb-c92817ce8d63df3e3c7225d77723f1c4ae725f58.tar.gz
gdb-c92817ce8d63df3e3c7225d77723f1c4ae725f58.tar.bz2
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.
-rw-r--r--gdb/ChangeLog9
-rw-r--r--gdb/completer.c11
-rw-r--r--gdb/gdbtypes.c20
-rw-r--r--gdb/parse.c14
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.base/completion.exp19
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 <tromey@redhat.com>
+
+ 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 <pedro@codesourcery.com>
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 <tromey@redhat.com>
+
+ PR symtab/11919:
+ * gdb.base/completion.exp: Add test.
+
2010-08-18 Doug Evans <dje@google.com>
* 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"