This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA] Fix regexp problem with "operator* etc.
- To: gdb-patches at sources dot redhat dot com
- Subject: [RFA] Fix regexp problem with "operator* etc.
- From: Michael Snyder <msnyder at cygnus dot com>
- Date: Thu, 01 Nov 2001 18:25:14 -0800
- CC: mec at shout dot net, jimb at redhat dot com, ezannoni at redhat dot com
- Organization: Red Hat
The following operations --
info func operator*
info func operator*=
info func operator->*
info func operator[]
info func operator char*
will cause gdb to do something other than was (probably) intended,
because the argument to the info function command is a regular
expression, and the "*" and "[]" bits will be interpreted by the
regular expression parser.
This patch will allow the user to quote these function names eg.
info func operator\*
info func operator\*=
info func operator->\*
info func operator\[\]
info func operator char\*
and thereby avoid having to treat them as special cases against
the regular expression language.
I also caught a case where alloca was being used to allocate a
buffer that was too small, thereby running the risk of corrupting
the stack.
A patch to the testsuite is included, which eliminates five fails.
2001-11-01 Michael Snyder <msnyder@redhat.com>
* symtab.c (operator_chars): Allow '*' and '[' to be quoted in
operator names, to avoid regexp expansion.
(search_symbols): Alloca buffer is too small, may get clobbered.
* gdb.c++/cplusfuncs.exp: Fix conflicts between operator names
and regular expression operators by using quoting.
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.46
diff -c -3 -p -r1.46 symtab.c
*** symtab.c 2001/10/17 07:12:57 1.46
--- symtab.c 2001/11/02 02:08:54
*************** operator_chars (char *p, char **end)
*** 2067,2119 ****
return p;
}
! switch (*p)
! {
! case '!':
! case '=':
! case '*':
! case '/':
! case '%':
! case '^':
! if (p[1] == '=')
! *end = p + 2;
! else
*end = p + 1;
! return p;
! case '<':
! case '>':
! case '+':
! case '-':
! case '&':
! case '|':
! if (p[1] == '=' || p[1] == p[0])
*end = p + 2;
! else
! *end = p + 1;
! return p;
! case '~':
! case ',':
! *end = p + 1;
! return p;
! case '(':
! if (p[1] != ')')
! error ("`operator ()' must be specified without whitespace in `()'");
! *end = p + 2;
! return p;
! case '?':
! if (p[1] != ':')
! error ("`operator ?:' must be specified without whitespace in `?:'");
! *end = p + 2;
! return p;
! case '[':
! if (p[1] != ']')
! error ("`operator []' must be specified without whitespace in `[]'");
! *end = p + 2;
! return p;
! default:
! error ("`operator %s' not supported", p);
! break;
! }
*end = "";
return *end;
}
--- 2067,2168 ----
return p;
}
! while (*p)
! switch (*p)
! {
! case '\\': /* regexp quoting */
! if (p[1] == '*')
! {
! if (p[2] == '=') /* 'operator\*=' */
! *end = p + 3;
! else /* 'operator\*' */
! *end = p + 2;
! return p;
! }
! else if (p[1] == '[')
! {
! if (p[2] == ']')
! error ("mismatched quoting on brackets, try 'operator\\[\\]'");
! else if (p[2] == '\\' && p[3] == ']')
! {
! *end = p + 4; /* 'operator\[\]' */
! return p;
! }
! else
! error ("nothing is allowed between '[' and ']'");
! }
! else
! {
! /* Gratuitous qoute: skip it and move on. */
! p++;
! continue;
! }
! break;
! case '!':
! case '=':
! case '*':
! case '/':
! case '%':
! case '^':
! if (p[1] == '=')
! *end = p + 2;
! else
! *end = p + 1;
! return p;
! case '<':
! case '>':
! case '+':
! case '-':
! case '&':
! case '|':
! if (p[0] == '-' && p[1] == '>')
! {
! /* Struct pointer member operator 'operator->'. */
! if (p[2] == '*')
! {
! *end = p + 3; /* 'operator->*' */
! return p;
! }
! else if (p[2] == '\\')
! {
! *end = p + 4; /* Hopefully 'operator->\*' */
! return p;
! }
! else
! {
! *end = p + 2; /* 'operator->' */
! return p;
! }
! }
! if (p[1] == '=' || p[1] == p[0])
! *end = p + 2;
! else
! *end = p + 1;
! return p;
! case '~':
! case ',':
*end = p + 1;
! return p;
! case '(':
! if (p[1] != ')')
! error ("`operator ()' must be specified without whitespace in `()'");
*end = p + 2;
! return p;
! case '?':
! if (p[1] != ':')
! error ("`operator ?:' must be specified without whitespace in `?:'");
! *end = p + 2;
! return p;
! case '[':
! if (p[1] != ']')
! error ("`operator []' must be specified without whitespace in `[]'");
! *end = p + 2;
! return p;
! default:
! error ("`operator %s' not supported", p);
! break;
! }
!
*end = "";
return *end;
}
*************** search_symbols (char *regexp, namespace_
*** 2365,2371 ****
/* If wrong number of spaces, fix it. */
if (fix >= 0)
{
! char *tmp = (char *) alloca (opend - opname + 10);
sprintf (tmp, "operator%.*s%s", fix, " ", opname);
regexp = tmp;
}
--- 2414,2420 ----
/* If wrong number of spaces, fix it. */
if (fix >= 0)
{
! char *tmp = (char *) alloca (strlen (regexp) + fix);
sprintf (tmp, "operator%.*s%s", fix, " ", opname);
regexp = tmp;
}
Index: testsuite/gdb.c++/cplusfuncs.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/cplusfuncs.exp,v
retrieving revision 1.2
diff -c -3 -p -r1.2 cplusfuncs.exp
*** cplusfuncs.exp 2001/02/14 19:54:04 1.2
--- cplusfuncs.exp 2001/11/02 02:08:54
*************** if { [gdb_compile "${srcdir}/${subdir}/
*** 60,65 ****
--- 60,66 ----
set dm_operator_comma ","
set dm_type_char_star "char*"
+ set dm_type_char_star_quoted "char\\*"
set dm_type_foo_ref "foo&"
set dm_type_int_star "int*"
set dm_type_long_star "long*"
*************** proc probe_demangler { } {
*** 71,76 ****
--- 72,78 ----
global gdb_prompt
global dm_operator_comma
global dm_type_char_star
+ global dm_type_char_star_quoted
global dm_type_foo_ref
global dm_type_int_star
global dm_type_long_star
*************** proc probe_demangler { } {
*** 102,107 ****
--- 104,110 ----
-re ".*dm_type_char_star\\(char \\*\\).*\r\n$gdb_prompt $" {
# v2 demangler
set dm_type_char_star "char *"
+ set dm_type_char_star_quoted "char \\*"
pass "detect dm_type_char_star"
}
-re ".*dm_type_char_star\\(char\\*\\).*\r\n$gdb_prompt $" {
*************** proc print_addr { name } {
*** 312,317 ****
--- 315,321 ----
proc test_lookup_operator_functions {} {
global dm_operator_comma
global dm_type_char_star
+ global dm_type_char_star_quoted
global dm_type_foo_ref
global dm_type_void
global dm_type_void_star
*************** proc test_lookup_operator_functions {} {
*** 323,329 ****
return
}
! info_func "operator*(" "void foo::operator*($dm_type_foo_ref);"
info_func "operator%(" "void foo::operator%($dm_type_foo_ref);"
info_func "operator-(" "void foo::operator-($dm_type_foo_ref);"
info_func "operator>>(" "void foo::operator>>($dm_type_foo_ref);"
--- 327,334 ----
return
}
! # operator* requires quoting so that GDB does not treat it as a regexp.
! info_func "operator\\*(" "void foo::operator*($dm_type_foo_ref);"
info_func "operator%(" "void foo::operator%($dm_type_foo_ref);"
info_func "operator-(" "void foo::operator-($dm_type_foo_ref);"
info_func "operator>>(" "void foo::operator>>($dm_type_foo_ref);"
*************** proc test_lookup_operator_functions {} {
*** 336,342 ****
info_func "operator++(" "void foo::operator++(int);"
info_func "operator=(" "void foo::operator=($dm_type_foo_ref);"
info_func "operator+=(" "void foo::operator+=($dm_type_foo_ref);"
! info_func "operator*=(" "void foo::operator*=($dm_type_foo_ref);"
info_func "operator%=(" "void foo::operator%=($dm_type_foo_ref);"
info_func "operator>>=(" "void foo::operator>>=($dm_type_foo_ref);"
info_func "operator|=(" "void foo::operator|=($dm_type_foo_ref);"
--- 341,348 ----
info_func "operator++(" "void foo::operator++(int);"
info_func "operator=(" "void foo::operator=($dm_type_foo_ref);"
info_func "operator+=(" "void foo::operator+=($dm_type_foo_ref);"
! # operator*= requires quoting so that GDB does not treat it as a regexp.
! info_func "operator\\*=(" "void foo::operator*=($dm_type_foo_ref);"
info_func "operator%=(" "void foo::operator%=($dm_type_foo_ref);"
info_func "operator>>=(" "void foo::operator>>=($dm_type_foo_ref);"
info_func "operator|=(" "void foo::operator|=($dm_type_foo_ref);"
*************** proc test_lookup_operator_functions {} {
*** 359,368 ****
info_func "operator<<=(" "void foo::operator<<=($dm_type_foo_ref);"
info_func "operator&=(" "void foo::operator&=($dm_type_foo_ref);"
info_func "operator^=(" "void foo::operator^=($dm_type_foo_ref);"
! info_func "operator->*(" "void foo::operator->*($dm_type_foo_ref);"
! # operator[] needs backslashes to protect against TCL evaluation.
! info_func "operator\[\](" "void foo::operator\[\]($dm_type_foo_ref);"
# These are gnarly because they might end with 'static'.
set dm_type_void_star_regexp [string_to_regexp $dm_type_void_star]
--- 365,377 ----
info_func "operator<<=(" "void foo::operator<<=($dm_type_foo_ref);"
info_func "operator&=(" "void foo::operator&=($dm_type_foo_ref);"
info_func "operator^=(" "void foo::operator^=($dm_type_foo_ref);"
! # operator->* requires quoting so that GDB does not treat it as a regexp.
! info_func "operator->\\*(" "void foo::operator->*($dm_type_foo_ref);"
! # operator[] needs double backslashes, so that a single backslash
! # will be sent to GDB, preventing the square brackets from being
! # evaluated as a regular expression.
! info_func "operator\\\[\\\](" "void foo::operator\[\]($dm_type_foo_ref);"
# These are gnarly because they might end with 'static'.
set dm_type_void_star_regexp [string_to_regexp $dm_type_void_star]
*************** proc test_lookup_operator_functions {} {
*** 371,377 ****
info_func "operator int(" "int foo::operator int($dm_type_void);"
info_func "operator()(" "void foo::operator()($dm_type_foo_ref);"
! info_func "operator $dm_type_char_star\(" \
"char *foo::operator $dm_type_char_star\($dm_type_void);"
}
--- 380,386 ----
info_func "operator int(" "int foo::operator int($dm_type_void);"
info_func "operator()(" "void foo::operator()($dm_type_foo_ref);"
! info_func "operator $dm_type_char_star_quoted\(" \
"char *foo::operator $dm_type_char_star\($dm_type_void);"
}