* [PATCH] fix PR c++/16117
@ 2013-11-04 22:21 Tom Tromey
2013-11-05 2:34 ` Doug Evans
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Tom Tromey @ 2013-11-04 22:21 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
This patch fixes PR c++/16117.
gdb has an extension so that users can use expressions like FILE::NAME
to choose a variable of the given name from the given file. The bug
is that this extension takes precedence over ordinary C++ expressions
of the same form. You might think this is merely hypothetical, but
now that C++ headers commonly do not use an extension, it is more
common.
This patch fixes the bug by making two related changes. First, it
changes gdb to prefer the ordinary C++ meaning of a symbol over the
extended meaning. Second, it arranges for single-quoting of the
symbol to indicate a preference for the extension.
Built and regtested on x86-64 Fedora 18.
New test case included.
2013-11-04 Tom Tromey <tromey@redhat.com>
PR c++/16117:
* c-exp.y (lex_one_token): Add "is_quoted_name" argument.
(classify_name): Likewise. Prefer a field of "this" over a
filename.
(classify_inner_name, yylex): Update.
2013-11-04 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Variables): Note gdb rules for ambiguous cases.
Add example.
2013-11-04 Tom Tromey <tromey@redhat.com>
* gdb.cp/includefile: New file.
* gdb.cp/filename.exp: New file.
* gdb.cp/filename.cc: New file.
---
gdb/ChangeLog | 8 ++++++
gdb/c-exp.y | 53 ++++++++++++++++++++++++++-------------
gdb/doc/ChangeLog | 5 ++++
gdb/doc/gdb.texinfo | 22 ++++++++++++----
gdb/testsuite/ChangeLog | 6 +++++
gdb/testsuite/gdb.cp/filename.cc | 36 ++++++++++++++++++++++++++
gdb/testsuite/gdb.cp/filename.exp | 37 +++++++++++++++++++++++++++
gdb/testsuite/gdb.cp/includefile | 18 +++++++++++++
8 files changed, 162 insertions(+), 23 deletions(-)
create mode 100644 gdb/testsuite/gdb.cp/filename.cc
create mode 100644 gdb/testsuite/gdb.cp/filename.exp
create mode 100644 gdb/testsuite/gdb.cp/includefile
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 77713dd..fecfd15 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -2415,7 +2415,7 @@ static int last_was_structop;
/* Read one token, getting characters through lexptr. */
static int
-lex_one_token (void)
+lex_one_token (int *is_quoted_name)
{
int c;
int namelen;
@@ -2425,6 +2425,7 @@ lex_one_token (void)
char *copy;
last_was_structop = 0;
+ *is_quoted_name = 0;
retry:
@@ -2669,6 +2670,8 @@ lex_one_token (void)
{
++tokstart;
namelen = lexptr - tokstart - 1;
+ *is_quoted_name = 1;
+
goto tryname;
}
else if (host_len > 1)
@@ -2813,10 +2816,11 @@ static struct obstack name_obstack;
/* Classify a NAME token. The contents of the token are in `yylval'.
Updates yylval and returns the new token type. BLOCK is the block
- in which lookups start; this can be NULL to mean the global
- scope. */
+ in which lookups start; this can be NULL to mean the global scope.
+ IS_QUOTED_NAME is non-zero if the name token was originally quoted
+ in single quotes. */
static int
-classify_name (const struct block *block)
+classify_name (const struct block *block, int is_quoted_name)
{
struct symbol *sym;
char *copy;
@@ -2840,16 +2844,6 @@ classify_name (const struct block *block)
}
else if (!sym)
{
- /* See if it's a file name. */
- struct symtab *symtab;
-
- symtab = lookup_symtab (copy);
- if (symtab)
- {
- yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
- return FILENAME;
- }
-
/* If we found a field of 'this', we might have erroneously
found a constructor where we wanted a type name. Handle this
case by noticing that we found a constructor and then look up
@@ -2869,6 +2863,24 @@ classify_name (const struct block *block)
return TYPENAME;
}
}
+
+ /* If we found a field, then we want to prefer it over a
+ filename. However, if the name was quoted, then it is better
+ to check for a filename or a block, since this is the only
+ way the user has of requiring the extension to be used. */
+ if (is_a_field_of_this.type == NULL || is_quoted_name)
+ {
+ /* See if it's a file name. */
+ struct symtab *symtab;
+
+ symtab = lookup_symtab (copy);
+ if (symtab)
+ {
+ yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab),
+ STATIC_BLOCK);
+ return FILENAME;
+ }
+ }
}
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
@@ -2938,7 +2950,7 @@ classify_inner_name (const struct block *block, struct type *context)
char *copy;
if (context == NULL)
- return classify_name (block);
+ return classify_name (block, 0);
type = check_typedef (context);
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
@@ -2986,6 +2998,7 @@ yylex (void)
struct type *context_type = NULL;
int last_to_examine, next_to_examine, checkpoint;
const struct block *search_block;
+ int is_quoted_name;
if (popping && !VEC_empty (token_and_value, token_fifo))
goto do_pop;
@@ -2994,9 +3007,9 @@ yylex (void)
/* Read the first token and decide what to do. Most of the
subsequent code is C++-only; but also depends on seeing a "::" or
name-like token. */
- current.token = lex_one_token ();
+ current.token = lex_one_token (&is_quoted_name);
if (current.token == NAME)
- current.token = classify_name (expression_context_block);
+ current.token = classify_name (expression_context_block, is_quoted_name);
if (parse_language->la_language != language_cplus
|| (current.token != TYPENAME && current.token != COLONCOLON
&& current.token != FILENAME))
@@ -3009,7 +3022,11 @@ yylex (void)
last_was_coloncolon = current.token == COLONCOLON;
while (1)
{
- current.token = lex_one_token ();
+ int ignore;
+
+ /* We ignore quoted names other than the very first one.
+ Subsequent ones do not have any special meaning. */
+ current.token = lex_one_token (&ignore);
current.value = yylval;
VEC_safe_push (token_and_value, token_fifo, ¤t);
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 28e6ff9..9737355 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -8322,11 +8322,23 @@ $4 = 0
@end smallexample
@cindex C@t{++} scope resolution
-These uses of @samp{::} are very rarely in conflict with the very similar
-use of the same notation in C@t{++}. @value{GDBN} also supports use of the C@t{++}
-scope resolution operator in @value{GDBN} expressions.
-@c FIXME: Um, so what happens in one of those rare cases where it's in
-@c conflict?? --mew
+These uses of @samp{::} are very rarely in conflict with the very
+similar use of the same notation in C@t{++}. When they are in
+conflict, the C@t{++} meaning takes precedence; however, this can be
+overridden by quoting the file or function name.
+
+For example, suppose the program is stopped in a method of a class
+that has a field named ``includefile'', and there is also an include
+file named ``includefile'' that defines a variable, ``some_global''.
+
+@smallexample
+(@value{GDBP}) p includefile
+$1 = 23
+(@value{GDBP}) p includefile::some_global
+A syntax error in expression, near `'.
+(@value{GDBP}) p 'includefile'::some_global
+$2 = 27
+@end smallexample
@cindex wrong values
@cindex variable values, wrong
diff --git a/gdb/testsuite/gdb.cp/filename.cc b/gdb/testsuite/gdb.cp/filename.cc
new file mode 100644
index 0000000..716f48b
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/filename.cc
@@ -0,0 +1,36 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2013 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "includefile"
+
+class C {
+public:
+ int includefile[1];
+
+ C() {
+ includefile[0] = 23;
+ }
+
+ void m() {
+ /* stop here */
+ }
+};
+
+int main() {
+ C c;
+ c.m();
+}
diff --git a/gdb/testsuite/gdb.cp/filename.exp b/gdb/testsuite/gdb.cp/filename.exp
new file mode 100644
index 0000000..943cdc6
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/filename.exp
@@ -0,0 +1,37 @@
+# Copyright 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if [get_compiler_info "c++"] {
+ return -1
+}
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+ return -1
+}
+
+if ![runto_main] then {
+ perror "couldn't run to main"
+ continue
+}
+
+gdb_breakpoint [gdb_get_line_number "stop here"]
+gdb_continue_to_breakpoint "stop here"
+
+gdb_test "print includefile\[0\]" " = 23"
+gdb_test "print 'includefile'::some_global" " = 27"
diff --git a/gdb/testsuite/gdb.cp/includefile b/gdb/testsuite/gdb.cp/includefile
new file mode 100644
index 0000000..9dfa787
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/includefile
@@ -0,0 +1,18 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2013 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+int some_global = 27;
--
1.8.1.4
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] fix PR c++/16117
2013-11-04 22:21 [PATCH] fix PR c++/16117 Tom Tromey
@ 2013-11-05 2:34 ` Doug Evans
2013-11-05 17:44 ` Tom Tromey
2013-11-05 9:15 ` Eli Zaretskii
2013-11-15 15:54 ` Tom Tromey
2 siblings, 1 reply; 7+ messages in thread
From: Doug Evans @ 2013-11-05 2:34 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
On Mon, Nov 4, 2013 at 1:16 PM, Tom Tromey <tromey@redhat.com> wrote:
> This patch fixes PR c++/16117.
>
> gdb has an extension so that users can use expressions like FILE::NAME
> to choose a variable of the given name from the given file. The bug
> is that this extension takes precedence over ordinary C++ expressions
> of the same form. You might think this is merely hypothetical, but
> now that C++ headers commonly do not use an extension, it is more
> common.
>
> This patch fixes the bug by making two related changes. First, it
> changes gdb to prefer the ordinary C++ meaning of a symbol over the
> extended meaning. Second, it arranges for single-quoting of the
> symbol to indicate a preference for the extension.
Do we need a NEWS entry for the change in behaviour?
Also, and this is just for discussion's sake,
I wonder if we'll ever need to handle nested quoting some day (blech :-)).
> [...]
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index 28e6ff9..9737355 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -8322,11 +8322,23 @@ $4 = 0
> @end smallexample
>
> @cindex C@t{++} scope resolution
> -These uses of @samp{::} are very rarely in conflict with the very similar
> -use of the same notation in C@t{++}. @value{GDBN} also supports use of the C@t{++}
> -scope resolution operator in @value{GDBN} expressions.
> -@c FIXME: Um, so what happens in one of those rare cases where it's in
> -@c conflict?? --mew
> +These uses of @samp{::} are very rarely in conflict with the very
> +similar use of the same notation in C@t{++}. When they are in
> +conflict, the C@t{++} meaning takes precedence; however, this can be
> +overridden by quoting the file or function name.
Can you add text to indicate "quoting" here means single-quotes *only*?
> +For example, suppose the program is stopped in a method of a class
> +that has a field named ``includefile'', and there is also an include
> +file named ``includefile'' that defines a variable, ``some_global''.
> +
> +@smallexample
> +(@value{GDBP}) p includefile
> +$1 = 23
> +(@value{GDBP}) p includefile::some_global
> +A syntax error in expression, near `'.
> +(@value{GDBP}) p 'includefile'::some_global
> +$2 = 27
> +@end smallexample
>
> @cindex wrong values
> @cindex variable values, wrong
> [...]
> diff --git a/gdb/testsuite/gdb.cp/filename.exp b/gdb/testsuite/gdb.cp/filename.exp
> new file mode 100644
> index 0000000..943cdc6
> --- /dev/null
> +++ b/gdb/testsuite/gdb.cp/filename.exp
> @@ -0,0 +1,37 @@
> +# Copyright 2013 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +if { [skip_cplus_tests] } { continue }
> +
> +standard_testfile .cc
> +
> +if [get_compiler_info "c++"] {
> + return -1
> +}
> +
> +if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
> + return -1
> +}
> +
> +if ![runto_main] then {
> + perror "couldn't run to main"
> + continue
> +}
> +
> +gdb_breakpoint [gdb_get_line_number "stop here"]
> +gdb_continue_to_breakpoint "stop here"
> +
> +gdb_test "print includefile\[0\]" " = 23"
> +gdb_test "print 'includefile'::some_global" " = 27"
Is 'class'::member intended to work? (static member or whatever)
[It works today, but I didn't check if that's intended. I presume it is.]
If so, maybe a test to verify that still works as well?
I grepped for "'::" in gdb.cp/*.exp and didn't find anything of use.
Since we're touching single-quote handling here, I figure this is as
good a place as any.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] fix PR c++/16117
2013-11-05 2:34 ` Doug Evans
@ 2013-11-05 17:44 ` Tom Tromey
2013-11-05 19:52 ` Tom Tromey
0 siblings, 1 reply; 7+ messages in thread
From: Tom Tromey @ 2013-11-05 17:44 UTC (permalink / raw)
To: Doug Evans; +Cc: gdb-patches
>>>>> "Doug" == Doug Evans <dje@google.com> writes:
Doug> Do we need a NEWS entry for the change in behaviour?
I don't think so.
Doug> Also, and this is just for discussion's sake,
Doug> I wonder if we'll ever need to handle nested quoting some day (blech :-)).
Let's just not.
Doug> Can you add text to indicate "quoting" here means single-quotes *only*?
I'll add a link.
Doug> Is 'class'::member intended to work? (static member or whatever)
Doug> [It works today, but I didn't check if that's intended. I presume it is.]
Doug> If so, maybe a test to verify that still works as well?
I think it's probably better to leave it undetermined.
On the one hand, I don't want to implement rejecting it.
I think that's too harsh.
On the other hand, defining it removes any flexibility in the future.
Tom
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] fix PR c++/16117
2013-11-04 22:21 [PATCH] fix PR c++/16117 Tom Tromey
2013-11-05 2:34 ` Doug Evans
@ 2013-11-05 9:15 ` Eli Zaretskii
2013-11-05 17:29 ` Tom Tromey
2013-11-15 15:54 ` Tom Tromey
2 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2013-11-05 9:15 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches, tromey
> From: Tom Tromey <tromey@redhat.com>
> Cc: Tom Tromey <tromey@redhat.com>
> Date: Mon, 4 Nov 2013 14:16:46 -0700
>
> +For example, suppose the program is stopped in a method of a class
> +that has a field named ``includefile'', and there is also an include
> +file named ``includefile'' that defines a variable, ``some_global''.
All these symbols in quotes should actually use the appropriate markup
instead: @code for C++ symbols, @file for file names.
The documentation part is OK with this fixed.
> +(@value{GDBP}) p includefile::some_global
> +A syntax error in expression, near `'.
I wonder if we can do better with the pointer to the place of the
syntax error: `' is not very specific ;-)
Thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] fix PR c++/16117
2013-11-05 9:15 ` Eli Zaretskii
@ 2013-11-05 17:29 ` Tom Tromey
0 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2013-11-05 17:29 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:
>> +(@value{GDBP}) p includefile::some_global
>> +A syntax error in expression, near `'.
Eli> I wonder if we can do better with the pointer to the place of the
Eli> syntax error: `' is not very specific ;-)
It would be nice, but it's a different bug.
Tom
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] fix PR c++/16117
2013-11-04 22:21 [PATCH] fix PR c++/16117 Tom Tromey
2013-11-05 2:34 ` Doug Evans
2013-11-05 9:15 ` Eli Zaretskii
@ 2013-11-15 15:54 ` Tom Tromey
2 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2013-11-15 15:54 UTC (permalink / raw)
To: gdb-patches
>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:
Tom> This patch fixes PR c++/16117.
I'm checking this in now.
Tom
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-11-15 15:53 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-04 22:21 [PATCH] fix PR c++/16117 Tom Tromey
2013-11-05 2:34 ` Doug Evans
2013-11-05 17:44 ` Tom Tromey
2013-11-05 19:52 ` Tom Tromey
2013-11-05 9:15 ` Eli Zaretskii
2013-11-05 17:29 ` Tom Tromey
2013-11-15 15:54 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox