2003-06-30 David Carlton <carlton@kealia.com>

Band-aid for PR c++/1245.
	* Makefile.in (cp-support.o): Depend on complaints_h.
	* cp-support.c: Include complaints.h.  Add declaration for
	find_last_component.
	(cp_find_first_component): Separate code into
	cp_find_first_component_aux.
	(cp_find_first_component_aux): Call demangled_name_complaint.
	(demangled_name_complaint): New.

2003-06-30  David Carlton  <carlton@kealia.com>

	* gdb.c++/maint.exp (test_invalid_name): New.
	(test_first_component): Add tests for invalid names.
This commit is contained in:
David Carlton 2003-06-30 16:21:16 +00:00
parent a257b5bbf7
commit b2a7f303a2
5 changed files with 98 additions and 14 deletions

View File

@ -1,3 +1,14 @@
2003-06-30 David Carlton <carlton@kealia.com>
Band-aid for PR c++/1245.
* Makefile.in (cp-support.o): Depend on complaints_h.
* cp-support.c: Include complaints.h. Add declaration for
find_last_component.
(cp_find_first_component): Separate code into
cp_find_first_component_aux.
(cp_find_first_component_aux): Call demangled_name_complaint.
(demangled_name_complaint): New.
2003-06-30 Andrew Cagney <cagney@redhat.com>
* remote.c (remote_write_bytes): Explicitly compute and then use

View File

@ -1647,7 +1647,7 @@ cp-namespace.o: cp-namespace.c $(defs_h) $(cp_support_h) $(gdb_obstack_h) \
$(symtab_h) $(symfile_h) $(gdb_assert_h) $(block_h)
cp-support.o: cp-support.c $(defs_h) $(cp_support_h) $(gdb_string_h) \
$(demangle_h) $(gdb_assert_h) $(gdbcmd_h) $(dictionary_h) \
$(objfiles_h) $(frame_h) $(block_h)
$(objfiles_h) $(frame_h) $(block_h) $(complaints_h)
cp-valprint.o: cp-valprint.c $(defs_h) $(gdb_obstack_h) $(symtab_h) \
$(gdbtypes_h) $(expression_h) $(value_h) $(command_h) $(gdbcmd_h) \
$(demangle_h) $(annotate_h) $(gdb_string_h) $(c_lang_h) $(target_h) \

View File

@ -32,6 +32,16 @@
#include "frame.h"
#include "symtab.h"
#include "block.h"
#include "complaints.h"
/* Functions related to demangled name parsing. */
static const char *find_last_component (const char *name);
static unsigned int cp_find_first_component_aux (const char *name,
int permissive);
static void demangled_name_complaint (const char *name);
/* Functions/variables related to overload resolution. */
@ -199,21 +209,32 @@ method_name_from_physname (const char *physname)
boundary of the first component: so, given 'A::foo' or 'A::B::foo'
it returns the 1, and given 'foo', it returns 0. */
/* Well, that's what it should do when called externally, but to make
the recursion easier, it also stops if it reaches an unexpected ')'
or '>'. */
/* The character in NAME indexed by the return value is guaranteed to
always be either ':' or '\0'. */
/* NOTE: carlton/2003-03-13: This function is currently only intended
for internal use: it's probably not entirely safe when called on
user-generated input, because some of the 'index += 2' lines might
go past the end of malformed input. */
user-generated input, because some of the 'index += 2' lines in
cp_find_first_component_aux might go past the end of malformed
input. */
unsigned int
cp_find_first_component (const char *name)
{
return cp_find_first_component_aux (name, 0);
}
/* Helper function for cp_find_first_component. Like that function,
it returns the length of the first component of NAME, but to make
the recursion easier, it also stops if it reaches an unexpected ')'
or '>' if the value of PERMISSIVE is nonzero. */
/* Let's optimize away calls to strlen("operator"). */
#define LENGTH_OF_OPERATOR 8
unsigned int
cp_find_first_component (const char *name)
static unsigned int
cp_find_first_component_aux (const char *name, int permissive)
{
unsigned int index = 0;
/* Operator names can show up in unexpected places. Since these can
@ -234,11 +255,15 @@ cp_find_first_component (const char *name)
terminating the component or a '::' between two
components. (Hence the '+ 2'.) */
index += 1;
for (index += cp_find_first_component (name + index);
for (index += cp_find_first_component_aux (name + index, 1);
name[index] != '>';
index += cp_find_first_component (name + index))
index += cp_find_first_component_aux (name + index, 1))
{
gdb_assert (name[index] == ':');
if (name[index] != ':')
{
demangled_name_complaint (name);
return strlen (name);
}
index += 2;
}
operator_possible = 1;
@ -246,17 +271,28 @@ cp_find_first_component (const char *name)
case '(':
/* Similar comment as to '<'. */
index += 1;
for (index += cp_find_first_component (name + index);
for (index += cp_find_first_component_aux (name + index, 1);
name[index] != ')';
index += cp_find_first_component (name + index))
index += cp_find_first_component_aux (name + index, 1))
{
gdb_assert (name[index] == ':');
if (name[index] != ':')
{
demangled_name_complaint (name);
return strlen (name);
}
index += 2;
}
operator_possible = 1;
break;
case '>':
case ')':
if (permissive)
return index;
else
{
demangled_name_complaint (name);
return strlen (name);
}
case '\0':
case ':':
return index;
@ -315,6 +351,16 @@ cp_find_first_component (const char *name)
}
}
/* Complain about a demangled name that we don't know how to parse.
NAME is the demangled name in question. */
static void
demangled_name_complaint (const char *name)
{
complaint (&symfile_complaints,
"unexpected demangled name '%s'", name);
}
/* If NAME is the fully-qualified name of a C++
function/variable/method/etc., this returns the length of its
entire prefix: all of the namespaces and classes that make up its

View File

@ -1,3 +1,8 @@
2003-06-30 David Carlton <carlton@kealia.com>
* gdb.c++/maint.exp (test_invalid_name): New.
(test_first_component): Add tests for invalid names.
2003-06-29 Michael Chastain <mec@shout.net>
* gdb.c++/inherit.exp (test_print_svi_classes): Accept gdb

View File

@ -45,7 +45,19 @@ proc test_single_component {name} {
gdb_test "maint cp first_component $name" "$matchname"
}
# This is used when NAME is invalid.
proc test_invalid_name {name} {
set matchname [string_to_regexp "$name"]
gdb_test "maint cp first_component $name" \
"During symbol reading, unexpected demangled name '$matchname'.\r\n$matchname"
}
proc test_first_component {} {
# The function in question might complain; make sure that we see
# all complaints.
gdb_test "set complaints -1" ""
test_single_component "foo"
test_single_component "operator<<"
test_single_component "operator>>"
@ -79,6 +91,16 @@ proc test_first_component {} {
gdb_test "maint cp first_component foo::bar::baz" "foo"
gdb_test "maint cp first_component C<A>::bar" "C<A>"
gdb_test "maint cp first_component C<std::basic_streambuf<wchar_t,std::char_traits<wchar_t> > >::bar" "C<std::basic_streambuf<wchar_t,std::char_traits<wchar_t> > >"
# Make sure we behave appropriately on invalid input.
# NOTE: carlton/2003-06-25: As of today, the demangler can in fact
# produce examples like the third case below: there really should
# be a space between the two <'s. See PR gdb/1245.
test_invalid_name "foo<"
test_invalid_name "foo("
test_invalid_name "bool operator<<char>"
}
gdb_exit