Re: [patch 0/3] Re: [RFA] c++/11734 revisited (and c++/12273)

Keith Seitz
2011-02-24T20:40:57Z

[-- Attachment #1: Type: text/plain, Size: 6153 bytes --]

On 02/21/2011 03:06 AM, Jan Kratochvil wrote:

> pre-physname:
> GNU gdb (GDB) 7.1.50.20100309-cvs
> (gdb) b A::outer::foo (int)
> Breakpoint 1 at 0x4005a3: file ./gdb.cp/ovsrch3.cc, line 23.
> (gdb) b A::outer::foo (void)
> Breakpoint 2 at 0x40058c: file ./gdb.cp/ovsrch2.cc, line 23.
> (gdb) b A::outer::foo (char *)
> Breakpoint 3 at 0x4005c0: file ./gdb.cp/ovsrch4.cc, line 23.
>
> patched:
> GNU gdb (GDB) 7.2.50.20110220-cvs
> (gdb) b A::outer::foo (int)
> the class A::outer does not have any method named foo (int)

This is caused by one of the consequences of dwarf2_physname: we need to
have all user input canonicalized before calling lookup_symbol[*]. This
is a problem I have wondered about since the dwarf2_physname patchset
was originally committed, and now we have a concrete example of how to
trigger this.

IIRC, the only functional changes (excluding requested changes) to the
patchset are:

- canonicalization of user input in find_methods (linespec.c)
- add tests to ovsrch.exp et al to cover the regressions you've identified

> It assumes get_gdb_completer_quote_characters() is just "'" as currently is.
> It cannot be changed now anyway and for future it should be rather removed
> than extended. It was already hardcoded into decode_compound before physname
> patch.

Yes, that was sloppy on my part. I apologize. I have reintroduced the
use of get_gdb_completer_quote_characters. IMO there's something to be
said for consistency. One day, we'll want to identify the places where
this assumption is made, and using get_gdb_completer_quote_characters is
undoubtedly going to be the key to doing it.

> Ã‰xcessive backslash.

Fixed all of these.

> Some comment and/or removal wrt get_gdb_completer_quote_characters for '.
> (OK, this ' hardcoded in decode_compound was present even before physname,
> I can clean it up afterwards.)

If I have understood you correctly, I've removed the quote character and
tested independently for it using get_gdb_completer_quote_characters.

> *p can == '\0' here, it works - but I would prefer for better readability:

Fixed.

> 00000000004004ea W _ZNK1C1mEv
> 00000000004004ea W C::m() const
>
> pre-physname:
> GNU gdb (GDB) 7.1.50.20100309-cvs
> (gdb) b C::m if C::m()
> Breakpoint 1 at 0x4004f2: file 3.C, line 4.
> (gdb) b 'C::m' if C::m()
> Breakpoint 1 at 0x4004f2: file 3.C, line 4.
>
> patched:
> GNU gdb (GDB) 7.2.50.20110220-cvs
> (gdb) b C::m if C::m()
> the class C does not have any method named m if C::m()
> (gdb) b 'C::m' if C::m()
> the class C does not have any method named m' if C::m()

This is also fixed, and I have added a test for this to ovsrch.exp.

> 00000000004004ea W _ZNK1C1mEv
> 00000000004004ea W C::m() const
>
> pre-physname:
> GNU gdb (GDB) 7.1.50.20100309-cvs
> (gdb) b 'C::m() const'
> Breakpoint 1 at 0x4004f2: file 3.C, line 4.
>
> patched:
> GNU gdb (GDB) 7.2.50.20110220-cvs
> (gdb) b 'C::m() const'
> Junk at end of arguments.
>
> This is a regression.

This is also a consequence of (the lack of) canonicalization. I've
modified ovsrch.exp et al to test for this.

> Probably not meaningful for SYM_CLASS but isn't here appropriate rather
> SYMBOL_NATURAL_NAME? If SYMBOL_LINKAGE_NAME would be a mangled name for the
> class fully qualified name it would not work. But linkage name of a class
> type does not make sense so the suggested change is rather for code
> readability.

Changed.

>> +# Copyright 2010 Free Software Foundation, Inc.
>
> 2011

Fixed.

>
> if [prepare_for_testing ... ] {
> return -1
> }

Fixed.

> [nitpick] gdb_breakpoint already always prints FAIL if it fails.

Grr. Deep down, I knew that to be the case. For some reason, it looked
odd, so I added the fail clause. Fixed.

>> + Copyright 2010 Free Software Foundation, Inc.
>
> 2011

Fixed.

>> + set method "${class}::foo\($ovld\)"
>
> Excessive backslashes.

Fixed.

> [nitpick] gdb_breakpoint already always prints FAIL if it fails.
> (and below)

Fixed.

> if [prepare_for_testing ... ] {
> return -1
> }

Fixed.

> Sorry for the review delay.

It's a big patchset. It's not like I have nothing else to do! ;-)

I'm not sure whether it would be easier to diff the old and new
patchsets or just attach the whole thing. But I'm erring on the side of
"too much information."

Keith

ChangeLog
2011-02-24 Keith Seitz <keiths@redhat.com>

* linespec.c (find_methods): Canonicalize NAME before looking
up the symbol.

PR c++/12273
* linespec.c (locate_first_half): Keep overload information, too.
(decode_compound): Use a string to represent break characters
to escape the loop.
If P points to a break character, do not increment it.
For C++ and Java, keep overload information and relevant keywords.
If we cannot find a symbol, search the minimal symbols.

PR c++/11734
* linespec.c (decode_compound): Rename SAVED_ARG to
THE_REAL_SAVED_ARG.
Make a copy of THE_REAL_SAVED_ARG in SAVED_ARG and strip
single-quotes.
Pass a valid block to lookup_symbol.
(lookup_prefix_sym): Likewise.
(find_method): Construct search name based on SYM_CLASS instead
of SAVED_ARG.
* psymtab.c (lookup_partial_symbol): Add language parameter.
(lookup_symbol_aux_psymtabs): Likewise.
Don't assume that the psymtab we found was the right one. Search
for the desired symbol in the symtab to be certain.
(psymtab_search_name): New function.
(lookup_partial_symbol): Use psymtab_search_name.
Add language parameter.
(read_symtabs_for_function): Add language parameter and pass to
lookup_partial_symbol.
(find_symbol_file_from_partial): Likewise.
* symfile.h (struct quick_symbol_functions): Add language parameter
to lookup_symbol, expand_symtabs_for_function, and find_symbol_file.
* cp-support.c (make_symbol_overload_list): Update above API
changes.
* symtab.c (lookup_symbol_aux_quick): Pass the current language
to the quick symbol functions.
(basic_lookup_transparent_type_quick): Likewise.
(find_main_filename): Likewise.
* dwarf2_read.c (dw2_lookup_symbol): Add langauge parameter.
(dw2_expand_symtabs_for_function): Likewise.
(dw2_find_symbol_file): Likewise.

testsuite/ChangeLog
[unchanged from last time]

Keith

[-- Attachment #2: 11734-12273-3.patch --]
[-- Type: text/plain, Size: 25161 bytes --]

Index: linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.109
diff -u -p -r1.109 linespec.c
--- linespec.c 9 Jan 2011 03:08:57 -0000 1.109
+++ linespec.c 24 Feb 2011 20:36:35 -0000
@@ -213,6 +213,19 @@ find_methods (struct type *t, char *name
int i1 = 0;
int ibase;
char *class_name = type_name_no_tag (t);
+ struct cleanup *cleanup;
+ char *canon;
+
+ /* NAME is typed by the user: it needs to be canonicalized before
+ passing to lookup_symbol. */
+ canon = cp_canonicalize_string (name);
+ if (canon != NULL)
+ {
+ name = canon;
+ cleanup = make_cleanup (xfree, name);
+ }
+ else
+ cleanup = make_cleanup (null_cleanup, NULL);

/* Ignore this class if it doesn't have a name. This is ugly, but
unless we figure out how to get the physname without the name of
@@ -275,6 +288,7 @@ find_methods (struct type *t, char *name
i1 += find_methods (TYPE_BASECLASS (t, ibase), name,
language, sym_arr + i1);

+ do_cleanups (cleanup);
return i1;
}

@@ -1057,6 +1071,10 @@ locate_first_half (char **argptr, int *i
error (_("malformed template specification in command"));
p = temp_end;
}
+
+ if (p[0] == '(')
+ p = find_method_overload_end (p);
+
/* Check for a colon and a plus or minus and a [ (which
indicates an Objective-C method). */
if (is_objc_method_format (p))
@@ -1226,7 +1244,7 @@ decode_objc (char **argptr, int funfirst

static struct symtabs_and_lines
decode_compound (char **argptr, int funfirstline, char ***canonical,
- char *saved_arg, char *p, int *not_found_ptr)
+ char *the_real_saved_arg, char *p, int *not_found_ptr)
{
struct symtabs_and_lines values;
char *p2;
@@ -1237,6 +1255,23 @@ decode_compound (char **argptr, int funf
struct symbol *sym_class;
struct type *t;
char *saved_java_argptr = NULL;
+ char *saved_arg;
+
+ /* If the user specified any completer quote characters in the input,
+ strip them. They are superfluous. */
+ saved_arg = alloca (strlen (the_real_saved_arg) + 1);
+ {
+ char *dst = saved_arg;
+ char *src = the_real_saved_arg;
+ char *quotes = get_gdb_completer_quote_characters ();
+ while (*src != '\0')
+ {
+ if (strchr (quotes, *src) == NULL)
+ *dst++ = *src;
+ ++src;
+ }
+ *dst = '\0';
+ }

/* First check for "global" namespace specification, of the form
"::foo". If found, skip over the colons and jump to normal
@@ -1253,8 +1288,10 @@ decode_compound (char **argptr, int funf
find_method.

2) AAA::inA isn't the name of a class. In that case, either the
- user made a typo or AAA::inA is the name of a namespace.
- Either way, we just look up AAA::inA::fun with lookup_symbol.
+ user made a typo, AAA::inA is the name of a namespace, or it is
+ the name of a minimal symbol.
+ We just look up AAA::inA::fun with lookup_symbol. If that fails,
+ try lookup_minimal_symbol.

Thus, our first task is to find everything before the last set of
double-colons and figure out if it's the name of a class. So we
@@ -1275,6 +1312,8 @@ decode_compound (char **argptr, int funf

while (1)
{
+ static char *break_characters = " \t(";
+
/* Move pointer up to next possible class/namespace token. */

p = p2 + 1; /* Restart with old value +1. */
@@ -1285,8 +1324,9 @@ decode_compound (char **argptr, int funf
/* PASS2: p2->"::fun", p->":fun" */

/* Move pointer ahead to next double-colon. */
- while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')
- && (*p != '('))
+ while (*p
+ && strchr (break_characters, *p) == NULL
+ && strchr (get_gdb_completer_quote_characters (), *p) == NULL)
{
if (current_language->la_language == language_cplus)
p += cp_validate_operator (p);
@@ -1310,9 +1350,12 @@ decode_compound (char **argptr, int funf
else if ((p[0] == ':') && (p[1] == ':'))
break; /* Found double-colon. */
else
- /* PASS2: We'll keep getting here, until p->"", at which point
- we exit this loop. */
- p++;
+ {
+ /* PASS2: We'll keep getting here, until P points to one of the
+ break characters, at which point we exit this loop. */
+ if (*p && strchr (break_characters, *p) == NULL)
+ p++;
+ }
}

if (*p != ':')
@@ -1321,7 +1364,7 @@ decode_compound (char **argptr, int funf
unsuccessfully all the components of the
string, and p->""(PASS2). */

- /* We get here if p points to ' ', '\t', '\'', "::" or ""(i.e
+ /* We get here if p points to one of the break characters or "" (i.e.,
string ended). */
/* Save restart for next time around. */
p2 = p;
@@ -1472,6 +1515,18 @@ decode_compound (char **argptr, int funf
/* We couldn't find a class, so we're in case 2 above. We check the
entire name as a symbol instead. */

+ if (current_language->la_language == language_cplus
+ || current_language->la_language == language_java)
+ {
+ char *paren = strchr (p, '(');
+ if (paren != NULL)
+ p = find_method_overload_end (paren);
+
+ /* Make sure we keep important kewords like "const" */
+ if (strncmp (p, " const", 6) == 0)
+ p += 6;
+ }
+
copy = (char *) alloca (p - saved_arg2 + 1);
memcpy (copy, saved_arg2, p - saved_arg2);
/* Note: if is_quoted should be true, we snuff out quote here
@@ -1481,15 +1536,24 @@ decode_compound (char **argptr, int funf
*argptr = (*p == '\'') ? p + 1 : p;

/* Look up entire name. */
- sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
+ sym = lookup_symbol (copy, get_selected_block (0), VAR_DOMAIN, 0);
if (sym)
return symbol_found (funfirstline, canonical, copy, sym, NULL);
+ else
+ {
+ struct minimal_symbol *msym;

- /* Couldn't find any interpretation as classes/namespaces, so give
- up. The quotes are important if copy is empty. */
+ /* Couldn't find any interpretation as classes/namespaces. As a last
+ resort, try the minimal symbol tables. */
+ msym = lookup_minimal_symbol (copy, NULL, NULL);
+ if (msym != NULL)
+ return minsym_found (funfirstline, msym);
+ }
+
+ /* Couldn't find a minimal symbol, either, so give up. */
if (not_found_ptr)
*not_found_ptr = 1;
- cplusplus_error (saved_arg,
+ cplusplus_error (the_real_saved_arg,
"Can't find member of namespace, "
"class, struct, or union named \"%s\"\n",
copy);
@@ -1528,7 +1592,7 @@ lookup_prefix_sym (char **argptr, char *
/* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA",
argptr->"inA::fun". */

- sym = lookup_symbol (copy, 0, STRUCT_DOMAIN, 0);
+ sym = lookup_symbol (copy, get_selected_block (0), STRUCT_DOMAIN, 0);
if (sym == NULL)
{
/* Typedefs are in VAR_DOMAIN so the above symbol lookup will
@@ -1599,17 +1663,29 @@ find_method (int funfirstline, char ***c
if (strchr (saved_arg, '(') != NULL)
{
int i;
- char *name = saved_arg;
- char *canon = cp_canonicalize_string (name);
+ char *name;
+ char *canon;
struct cleanup *cleanup;

+ /* Construct the proper search name based on SYM_CLASS and COPY.
+ SAVED_ARG may contain a valid name, but that name might not be
+ what is actually stored in the symbol table. For example,
+ if SAVED_ARG (and SYM_CLASS) were found via an import
+ ("using namespace" in C++), then the physname of
+ SYM_CLASS ("A::myclass") may not be the same as SAVED_ARG
+ ("myclass"). */
+ name = xmalloc (strlen (SYMBOL_NATURAL_NAME (sym_class))
+ + 2 /* "::" */ + strlen (copy) + 1);
+ strcpy (name, SYMBOL_NATURAL_NAME (sym_class));
+ strcat (name, "::");
+ strcat (name, copy);
+ canon = cp_canonicalize_string (name);
if (canon != NULL)
{
+ xfree (name);
name = canon;
- cleanup = make_cleanup (xfree, canon);
}
- else
- cleanup = make_cleanup (null_cleanup, NULL);
+ cleanup = make_cleanup (xfree, name);

for (i = 0; i < i1; ++i)
{
Index: psymtab.c
===================================================================
RCS file: /cvs/src/src/gdb/psymtab.c,v
retrieving revision 1.22
diff -u -p -r1.22 psymtab.c
--- psymtab.c 10 Jan 2011 20:38:50 -0000 1.22
+++ psymtab.c 24 Feb 2011 20:36:35 -0000
@@ -33,6 +33,8 @@
#include "readline/readline.h"
#include "gdb_regex.h"
#include "dictionary.h"
+#include "language.h"
+#include "cp-support.h"

#ifndef DEV_TTY
#define DEV_TTY "/dev/tty"
@@ -426,7 +428,26 @@ lookup_symbol_aux_psymtabs (struct objfi
ALL_OBJFILE_PSYMTABS (objfile, ps)
{
if (!ps->readin && lookup_partial_symbol (ps, name, psymtab_index, domain))
- return PSYMTAB_TO_SYMTAB (ps);
+ {
+ struct symbol *sym = NULL;
+ struct symtab *stab = PSYMTAB_TO_SYMTAB (ps);
+
+ /* Some caution must be observed with overloaded functions
+ and methods, since the psymtab will not contain any overload
+ information (but NAME might contain it). */
+ if (stab->primary)
+ {
+ struct blockvector *bv = BLOCKVECTOR (stab);
+ struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
+
+ sym = lookup_block_symbol (block, name, domain);
+ }
+
+ if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
+ return stab;
+
+ /* Keep looking through other psymtabs. */
+ }
}

return NULL;
@@ -519,6 +540,39 @@ pre_expand_symtabs_matching_psymtabs (st
/* Nothing. */
}

+/* Returns the name used to search psymtabs. Unlike symtabs, psymtabs do
+ not contain any method/function instance information (since this would
+ force reading type information while reading psymtabs). Therefore,
+ if NAME contains overload information, it must be stripped before searching
+ psymtabs.
+
+ The caller is responsible for freeing the return result. */
+
+static char *
+psymtab_search_name (const char *name)
+{
+ switch (current_language->la_language)
+ {
+ case language_cplus:
+ case language_java:
+ {
+ if (strchr (name, '('))
+ {
+ char *ret = cp_remove_params (name);
+
+ if (ret)
+ return ret;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return xstrdup (name);
+}
+
/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
Check the global symbols if GLOBAL, the static symbols if not. */

@@ -530,11 +584,16 @@ lookup_partial_symbol (struct partial_sy
struct partial_symbol **top, **real_top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms);
int do_linear_search = 1;
+ char *search_name;
+ struct cleanup *cleanup;

if (length == 0)
{
return (NULL);
}
+
+ search_name = psymtab_search_name (name);
+ cleanup = make_cleanup (xfree, search_name);
start = (global ?
pst->objfile->global_psymbols.list + pst->globals_offset :
pst->objfile->static_psymbols.list + pst->statics_offset);
@@ -563,7 +622,8 @@ lookup_partial_symbol (struct partial_sy
{
do_linear_search = 1;
}
- if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), name) >= 0)
+ if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center),
+ search_name) >= 0)
{
top = center;
}
@@ -577,11 +637,14 @@ lookup_partial_symbol (struct partial_sy
_("failed internal consistency check"));

while (top <= real_top
- && SYMBOL_MATCHES_SEARCH_NAME (*top, name))
+ && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
SYMBOL_DOMAIN (*top), domain))
- return (*top);
+ {
+ do_cleanups (cleanup);
+ return (*top);
+ }
top++;
}
}
@@ -595,11 +658,15 @@ lookup_partial_symbol (struct partial_sy
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
SYMBOL_DOMAIN (*psym), domain)
- && SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
- return (*psym);
+ && SYMBOL_MATCHES_SEARCH_NAME (*psym, search_name))
+ {
+ do_cleanups (cleanup);
+ return (*psym);
+ }
}
}

+ do_cleanups (cleanup);
return (NULL);
}

Index: testsuite/gdb.cp/cmpd-minsyms.cc
===================================================================
RCS file: testsuite/gdb.cp/cmpd-minsyms.cc
diff -N testsuite/gdb.cp/cmpd-minsyms.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cmpd-minsyms.cc 24 Feb 2011 20:36:35 -0000
@@ -0,0 +1,37 @@
+/* This test case is part of GDB, the GNU debugger.
+
+ Copyright 2011 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/>. */
+
+template <typename T>
+class GDB
+{
+ public:
+ static int simple (void) { return 0; }
+ static int harder (T a) { return 1; }
+ template <typename X>
+ static X even_harder (T a) { return static_cast<X> (a); }
+ int operator == (GDB const& other)
+ { return 1; }
+};
+
+int main(int argc, char **argv)
+{
+ GDB<int> a, b;
+ if (a == b)
+ return GDB<char>::harder('a') + GDB<int>::harder(3)
+ + GDB<char>::even_harder<int> ('a');
+ return GDB<int>::simple ();
+}
Index: testsuite/gdb.cp/cmpd-minsyms.exp
===================================================================
RCS file: testsuite/gdb.cp/cmpd-minsyms.exp
diff -N testsuite/gdb.cp/cmpd-minsyms.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cmpd-minsyms.exp 24 Feb 2011 20:36:35 -0000
@@ -0,0 +1,50 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# Contributed by Red Hat, originally written by Keith Seitz.
+#
+# 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/>.
+
+# This file is part of the gdb testsuite.
+
+if {[skip_cplus_tests]} { continue }
+
+# Test for c++/12273
+set testfile "cmpd-minsyms"
+# Do NOT compile with debug flag.
+if {[prepare_for_testing $testfile $testfile $testfile.cc {c++}]} {
+ return -1
+}
+
+gdb_test_no_output "set language c++"
+
+# A list of minimal symbol names to check.
+# Note that GDB<char>::even_harder<int>(char) is quoted and includes
+# the return type. This is necessary because this is the demangled name
+# of the minimal symbol.
+set min_syms [list \
+ "GDB<int>::operator ==" \
+ "GDB<int>::operator==(GDB<int> const&)" \
+ "GDB<char>::harder(char)" \
+ "GDB<int>::harder(int)" \
+ {"int GDB<char>::even_harder<int>(char)"} \
+ "GDB<int>::simple()"]
+
+foreach sym $min_syms {
+ set tst "setting breakpoint at $sym"
+ if {[gdb_breakpoint $sym]} {
+ pass $tst
+ }
+}
+
+gdb_exit
Index: testsuite/gdb.cp/ovsrch.exp
===================================================================
RCS file: testsuite/gdb.cp/ovsrch.exp
diff -N testsuite/gdb.cp/ovsrch.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch.exp 24 Feb 2011 20:36:35 -0000
@@ -0,0 +1,96 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# Contributed by Red Hat, originally written by Keith Seitz.
+#
+# 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/>.
+
+# This file is part of the gdb testsuite.
+
+proc test_class {class} {
+
+ # An array holding the overload types for the methods A::outer::foo
+ # and A::B::inner::foo. The first element is the overloaded method
+ # parameter. The second element is the expected source file number,
+ # e.g. "ovsrch?.cc".
+ array set tests {
+ "char*" 4
+ "int" 3
+ "void" 2
+ }
+
+ # Test each overload instance twice: once quoted, once unquoted
+ set conditional1 "if (a == 3)"
+ set conditional2 "if (A::outer::func ())"
+ foreach ovld [array names tests] {
+ set method "${class}::foo ($ovld) const"
+ set result "Breakpoint (\[0-9\]).*file .*/ovsrch$tests($ovld).*"
+ gdb_test "break $method" $result
+ gdb_test "break '$method'" $result
+
+ # Also test with a conditional tacked onto the end.
+ if {[string compare $ovld "void"] != 0} {
+ gdb_test "break $method $conditional1" $result
+ gdb_test "break '$method' $conditional1" $result
+ gdb_test "break $method $conditional2" $result
+ gdb_test "break '$method' $conditional2" $result
+ }
+ }
+}
+
+if { [skip_cplus_tests] } { continue }
+
+# Test for c++/11734
+set testfile "ovsrch"
+set binfile [file join $objdir $subdir $testfile]
+
+set srcfiles {}
+for {set i 1} {$i < 5} {incr i} {
+ lappend srcfiles $testfile$i.cc
+}
+
+if {[prepare_for_testing $testfile $testfile $srcfiles {c++ debug}]} {
+ return -1
+}
+
+if {![runto_main]} {
+ perror "couldn't run to breakpoint"
+ continue
+}
+
+# Break in A::stop_here and run tests.
+if {[gdb_breakpoint "stop_here"]} {
+ pass "break stop_here"
+}
+
+if {[gdb_breakpoint "'stop_here'"]} {
+ pass "break 'stop_here'"
+}
+
+gdb_continue_to_breakpoint "stop_here"
+test_class outer
+
+# Break in A::B::stop_here_too and run tests.
+if {[gdb_breakpoint "B::stop_here_too"]} {
+ pass "break B::stop_here_too"
+}
+
+if {[gdb_breakpoint "'B::stop_here_too'"]} {
+ pass "break 'B::stop_here_too'"
+}
+
+gdb_continue_to_breakpoint "stop_here_too"
+test_class inner
+
+gdb_exit
+return 0
Index: testsuite/gdb.cp/ovsrch.h
===================================================================
RCS file: testsuite/gdb.cp/ovsrch.h
diff -N testsuite/gdb.cp/ovsrch.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch.h 24 Feb 2011 20:36:35 -0000
@@ -0,0 +1,39 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 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/>. */
+
+namespace A
+{
+ class outer
+ {
+ public:
+ void foo (void) const;
+ void foo (int) const;
+ void foo (char *) const;
+ bool func (void) { return true; }
+ };
+
+ namespace B
+ {
+ class inner
+ {
+ public:
+ void foo (void) const;
+ void foo (int) const;
+ void foo (char *) const;
+ };
+ }
+}
Index: testsuite/gdb.cp/ovsrch1.cc
===================================================================
RCS file: testsuite/gdb.cp/ovsrch1.cc
diff -N testsuite/gdb.cp/ovsrch1.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch1.cc 24 Feb 2011 20:36:35 -0000
@@ -0,0 +1,41 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 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 "ovsrch.h"
+
+namespace A
+{
+ void stop_here (void) { }
+
+ namespace B
+ {
+ void stop_here_too (void) { }
+ }
+}
+
+using namespace A;
+
+int
+main ()
+{
+ outer *p = new outer;
+ stop_here ();
+ B::stop_here_too ();
+ p->foo ();
+ return 0;
+}
+
Index: testsuite/gdb.cp/ovsrch2.cc
===================================================================
RCS file: testsuite/gdb.cp/ovsrch2.cc
diff -N testsuite/gdb.cp/ovsrch2.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch2.cc 24 Feb 2011 20:36:35 -0000
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 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 "ovsrch.h"
+
+void
+A::outer::foo (void) const
+{
+}
+
+void
+A::B::inner::foo (void) const
+{
+}
Index: testsuite/gdb.cp/ovsrch3.cc
===================================================================
RCS file: testsuite/gdb.cp/ovsrch3.cc
diff -N testsuite/gdb.cp/ovsrch3.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch3.cc 24 Feb 2011 20:36:35 -0000
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 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 "ovsrch.h"
+
+void
+A::outer::foo (int a) const
+{
+}
+
+void
+A::B::inner::foo (int a) const
+{
+}
Index: testsuite/gdb.cp/ovsrch4.cc
===================================================================
RCS file: testsuite/gdb.cp/ovsrch4.cc
diff -N testsuite/gdb.cp/ovsrch4.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch4.cc 24 Feb 2011 20:36:35 -0000
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 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 "ovsrch.h"
+
+void
+A::outer::foo (char *a) const
+{
+}
+
+void
+A::B::inner::foo (char *a) const
+{
+}