aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2023-12-22 11:29:13 +0000
committerAndrew Burgess <aburgess@redhat.com>2024-01-04 09:24:18 +0000
commitb7a5722ebdd24a0d15d56e96d30a649ea1d7b0ee (patch)
tree17846ef2a41131008510993c370b92172320e768
parente89496f42ac7b2d6fbba15f98f3caf496de050f4 (diff)
downloadbinutils-b7a5722ebdd24a0d15d56e96d30a649ea1d7b0ee.zip
binutils-b7a5722ebdd24a0d15d56e96d30a649ea1d7b0ee.tar.gz
binutils-b7a5722ebdd24a0d15d56e96d30a649ea1d7b0ee.tar.bz2
gdb: improve error reporting from expression parser
This commits changes how errors are reported from the expression parser. Previously, parser errors were reported like this: (gdb) p a1 +}= 432 A syntax error in expression, near `}= 432'. (gdb) p a1 + A syntax error in expression, near `'. The first case is fine, a user can figure out what's going wrong, but the second case is a little confusing; as the error occurred at the end of the expression GDB just reports the empty string to the user. After this commit the first case is unchanged, but the second case now reports like this: (gdb) p a1 + A syntax error in expression, near the end of `a1 +'. Which I think is clearer. There is a possible issue if the expression being parsed is very long, GDB will repeat the whole expression. But this issue already exists in the standard case; if the error occurs early in a long expression GDB will repeat everything after the syntax error. So I've not worried about this case in my new code either, which keeps things simpler. I did consider trying to have multi-line errors here, in the style that gcc produces, with some kind of '~~~~~^' marker on the second line to indicate where the error occurred; but I rejected this due to the places in GDB where we catch an error and repackage the message within some longer string, I don't think multi-line error messages would work well in that case. At a minimum it would require some significant work in order to make all our error handling multi-line aware. I've added a couple of extra tests in gdb.base/exprs.exp. Approved-By: John Baldwin <jhb@FreeBSD.org>
-rw-r--r--gdb/parse.c6
-rw-r--r--gdb/parser-defs.h4
-rw-r--r--gdb/testsuite/gdb.base/exprs.exp8
3 files changed, 17 insertions, 1 deletions
diff --git a/gdb/parse.c b/gdb/parse.c
index efac0de..e8bb112 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -252,7 +252,11 @@ parser_state::parse_error (const char *msg)
if (this->prev_lexptr)
this->lexptr = this->prev_lexptr;
- error (_("A %s in expression, near `%s'."), msg, this->lexptr);
+ if (*this->lexptr == '\0')
+ error (_("A %s in expression, near the end of `%s'."),
+ msg, this->start_of_input);
+ else
+ error (_("A %s in expression, near `%s'."), msg, this->lexptr);
}
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 24522bb..4472898 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -152,6 +152,7 @@ struct parser_state : public expr_builder
expression_context_block (context_block),
expression_context_pc (context_pc),
lexptr (input),
+ start_of_input (input),
block_tracker (tracker),
comma_terminates ((flags & PARSER_COMMA_TERMINATES) != 0),
parse_completion (completion),
@@ -288,6 +289,9 @@ struct parser_state : public expr_builder
Currently used only for error reporting. */
const char *prev_lexptr = nullptr;
+ /* A pointer to the start of the full input, used for error reporting. */
+ const char *start_of_input = nullptr;
+
/* Number of arguments seen so far in innermost function call. */
int arglist_len = 0;
diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp
index 79ae905..8c85b57 100644
--- a/gdb/testsuite/gdb.base/exprs.exp
+++ b/gdb/testsuite/gdb.base/exprs.exp
@@ -275,3 +275,11 @@ gdb_test "print null_t_struct && null_t_struct->v_int_member == 0" \
# Regression test for unusual function-call parse that caused a crash.
gdb_test "print v_short++(97)" \
"cast the call to its declared return type"
+
+# Test for a syntax error at the end of an expression.
+gdb_test "print v_short + " \
+ "A syntax error in expression, near the end of `v_short \\+'\\."
+
+# Test for a syntax error in the middle of an expression.
+gdb_test "print v_short =}{= 3" \
+ "A syntax error in expression, near `\\}\\{= 3'\\."