This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA] Fix PR c++/17059
- From: Keith Seitz <keiths at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 24 Jun 2014 15:19:56 -0700
- Subject: [RFA] Fix PR c++/17059
- Authentication-results: sourceware.org; auth=none
This patch fixes PR c++/17059.
When inspect_type sees a typedef, it attempts to call type_print
to printout the target type's name.
when type_print calls c_type_print_base, this function simply "prints"
out TYPE_NAME ("do we want to print it as 'struct foo' or as 'bar'? Pick
the latter, because C++ folk tend to expect thngs like 'class5 *foo'
rather than 'struct class5 *foo'."). Since TYPE_NAME is the same as the
typedef name (in this case), we get the same name, which
print_name_maybe_canonical tries to do typedef substitution on. As a
result, an infinite recursion occurs.
This patch adds logic to inspect_type to recognize this situation and
bail typedef substitution if the typedef and its target type have the
same name.
ChangeLog
2014-06-24 Keith Seitz <keiths@redhat.com>
PR c++/17059
* cp-support.c (inspect_type): When a typedef's target type
has the same name as the typedef, do not attempt to do
any substitutions.
testsuite/ChangeLog
2014-06-24 Keith Seitz <keiths@redhat.com>
PR c++/17059
* gdb.cp/breakpoint.cc: Include stddef.h.
(opaque_struct): New typedef.
(C1::method_with_opaque): New method.
* gdb.cp/breakpoint.exp: Add test to set a breakpoint on
C1::method_with_opaque (opaque_struct *).
---
gdb/cp-support.c | 13 ++++++++++---
gdb/testsuite/gdb.cp/breakpoint.cc | 8 ++++++++
gdb/testsuite/gdb.cp/breakpoint.exp | 2 ++
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index a8ea6fc..f6d1b90 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -214,9 +214,16 @@ inspect_type (struct demangle_parse_info *info,
/* If the symbol is a namespace and its type name is no different
than the name we looked up, this symbol is not a namespace
- alias and does not need to be substituted. */
- if (TYPE_CODE (otype) == TYPE_CODE_NAMESPACE
- && strcmp (TYPE_NAME (type), name) == 0)
+ alias and does not need to be substituted.
+
+ Also, do not attempt to substitute a type that resolves
+ to the same name ("typedef struct foo foo;") since that
+ will cause type_print to try to canonicalize_no_typedefs
+ again. */
+ if ((TYPE_CODE (otype) == TYPE_CODE_NAMESPACE
+ && strcmp (TYPE_NAME (type), name) == 0)
+ || (TYPE_TAG_NAME (type) != NULL
+ && strcmp (TYPE_TAG_NAME (type), name) == 0))
return 0;
is_anon = (TYPE_TAG_NAME (type) == NULL
diff --git a/gdb/testsuite/gdb.cp/breakpoint.cc b/gdb/testsuite/gdb.cp/breakpoint.cc
index e2873ea..31d8cfa 100644
--- a/gdb/testsuite/gdb.cp/breakpoint.cc
+++ b/gdb/testsuite/gdb.cp/breakpoint.cc
@@ -17,8 +17,12 @@
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 <stddef.h>
+
int g = 0;
+typedef struct opaque_struct opaque_struct;
+
class C1 {
public:
C1(int i) : i_(i) {}
@@ -37,6 +41,9 @@ public:
}
}
+ void
+ method_with_opaque (opaque_struct *p) {}
+
class Nested {
public:
int
@@ -61,6 +68,7 @@ int main ()
c2.bar ();
c3.foo ();
c3.bar ();
+ c3.method_with_opaque (NULL);
return 0;
}
diff --git a/gdb/testsuite/gdb.cp/breakpoint.exp b/gdb/testsuite/gdb.cp/breakpoint.exp
index 7daaade..36dc4d2 100644
--- a/gdb/testsuite/gdb.cp/breakpoint.exp
+++ b/gdb/testsuite/gdb.cp/breakpoint.exp
@@ -56,6 +56,8 @@ gdb_test "print i_" "\\\$1 = 3" "check the member variable"
gdb_test "continue" ".*Breakpoint.*C1::bar.*" "continue to breakpoint"
gdb_test "print i_" "\\\$2 = 3" "check the member variable"
+# PR c++/17059
+gdb_breakpoint "C1::method_with_opaque (opaque_struct *)" message
gdb_exit
return 0
--
1.9.3