From 0def5aaad6a89e78f09cef2b95635dc3254ce304 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Thu, 26 Feb 2015 17:31:29 -0800 Subject: [PATCH] Add missing CHECK_TYPEDEF calls to recent vptr_{fieldno,basetype} cleanup. gdb/ChangeLog: * gdbtypes.c (internal_type_vptr_fieldno): Add missing call to CHECK_TYPEDEF. (set_type_vptr_fieldno): Ditto. (internal_type_vptr_basetype, set_type_vptr_basetype): Ditto. * gnu-v3-abi.c (gnuv3_dynamic_class): Ditto. gdb/testsuite/ChangeLog: * gdb.cp/class2.cc (Dbase, D): New classes. (main): New local delta. * gdb.cp/class2.exp: Test printing delta. * gdb.cp/classes.cc (DynamicBase2, DynamicBar): New classes. (dynbar): New global. * gdb.cp/classes.exp (test_ptype_class_objects): Test ptype DynamicBar. --- gdb/ChangeLog | 8 ++++++++ gdb/gdbtypes.c | 4 ++++ gdb/gnu-v3-abi.c | 1 + gdb/testsuite/ChangeLog | 9 +++++++++ gdb/testsuite/gdb.cp/class2.cc | 19 +++++++++++++++++++ gdb/testsuite/gdb.cp/class2.exp | 16 +++++++++++++++- gdb/testsuite/gdb.cp/classes.cc | 18 ++++++++++++++++++ gdb/testsuite/gdb.cp/classes.exp | 9 +++++++++ 8 files changed, 83 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b3d8650..fac8b37 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2015-02-26 Doug Evans + + * gdbtypes.c (internal_type_vptr_fieldno): Add missing call to + CHECK_TYPEDEF. + (set_type_vptr_fieldno): Ditto. + (internal_type_vptr_basetype, set_type_vptr_basetype): Ditto. + * gnu-v3-abi.c (gnuv3_dynamic_class): Ditto. + 2015-02-26 Pedro Alves * auto-load.h (file_is_auto_load_safe): Add ATTRIBUTE_PRINTF. diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index a80151c..ebb047f 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1636,6 +1636,7 @@ get_signed_type_minmax (struct type *type, LONGEST *min, LONGEST *max) int internal_type_vptr_fieldno (struct type *type) { + CHECK_TYPEDEF (type); gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION); if (!HAVE_CPLUS_STRUCT (type)) @@ -1648,6 +1649,7 @@ internal_type_vptr_fieldno (struct type *type) void set_type_vptr_fieldno (struct type *type, int fieldno) { + CHECK_TYPEDEF (type); gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION); if (!HAVE_CPLUS_STRUCT (type)) @@ -1661,6 +1663,7 @@ set_type_vptr_fieldno (struct type *type, int fieldno) struct type * internal_type_vptr_basetype (struct type *type) { + CHECK_TYPEDEF (type); gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION); gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_CPLUS_STUFF); @@ -1672,6 +1675,7 @@ internal_type_vptr_basetype (struct type *type) void set_type_vptr_basetype (struct type *type, struct type *basetype) { + CHECK_TYPEDEF (type); gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION); if (!HAVE_CPLUS_STRUCT (type)) diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index cdcb354..1dfb37b 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -202,6 +202,7 @@ gnuv3_dynamic_class (struct type *type) { int fieldnum, fieldelem; + CHECK_TYPEDEF (type); gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 183644f..373cec7 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-02-26 Doug Evans + + * gdb.cp/class2.cc (Dbase, D): New classes. + (main): New local delta. + * gdb.cp/class2.exp: Test printing delta. + * gdb.cp/classes.cc (DynamicBase2, DynamicBar): New classes. + (dynbar): New global. + * gdb.cp/classes.exp (test_ptype_class_objects): Test ptype DynamicBar. + 2015-02-26 Jan Kratochvil * gdb.compile/compile-ifunc.c: New file. diff --git a/gdb/testsuite/gdb.cp/class2.cc b/gdb/testsuite/gdb.cp/class2.cc index 617a8fa..409fb29 100644 --- a/gdb/testsuite/gdb.cp/class2.cc +++ b/gdb/testsuite/gdb.cp/class2.cc @@ -46,6 +46,23 @@ struct C : public B A *c2; }; +/* Use a typedef for the baseclass, with a virtual method, to exercise + gnu-v3-abi.c:gnuv3_dynamic_class recursion. It's important that the + class itself have no name to make sure the typedef makes it through + to the recursive call. */ +typedef class { + public: + /* This class has no members as gcc 4.9.x doesn't emit the debug info + for them. */ + virtual int get () { return 42; } +} Dbase; + +class D : public Dbase +{ + public: + int d1; +}; + // Stop the compiler from optimizing away data. void refer (A *) { @@ -65,12 +82,14 @@ int main (void) A alpha, *aap, *abp, *acp; B beta, *bbp; C gamma; + D delta; empty e; A &aref (alpha); alpha.a1 = 100; beta.a1 = 200; beta.b1 = 201; beta.b2 = 202; gamma.c1 = 0; gamma.c2 = (A *) ~0UL; + delta.d1 = 400; aap = α refer (aap); abp = β refer (abp); diff --git a/gdb/testsuite/gdb.cp/class2.exp b/gdb/testsuite/gdb.cp/class2.exp index 7fedc58..81b3561 100644 --- a/gdb/testsuite/gdb.cp/class2.exp +++ b/gdb/testsuite/gdb.cp/class2.exp @@ -101,17 +101,31 @@ gdb_test "print * (B *) abp" \ "= {.*a1 = 200.*b1 = 201.*b2 = 202}" \ "print * (B *) abp at marker return 0" +# Print the "D" object. + +gdb_test "print delta" \ + "= {.*d1 = 400}" \ + "print delta with \"print object\" off" + # Printing the value of an object containing no data fields: gdb_test "p e" "= \{\}" "print object with no data fields" -# Printing NULL pointers with "set print object on" +# Printing NULL pointers with "set print object on". gdb_test_no_output "set print object on" gdb_test "p acp" "= \\(C \\*\\) ${hex}" gdb_test "p acp->c1" "\\(A \\*\\) 0x0" gdb_test "p acp->c2" "\\(A \\*\\) ${hex}f" +# Print the "D" object with "set print object on". +# There's no difference in output, but this exercises vtable lookup +# with a typedef'd baseclass. + +gdb_test "print delta" \ + "= {.*d1 = 400}" \ + "print delta with \"print object\" on" + # Regression test for PR c++/15401. # Check that the type printed is a reference. gdb_test "p aref" " = \\(A \\&\\) .*" diff --git a/gdb/testsuite/gdb.cp/classes.cc b/gdb/testsuite/gdb.cp/classes.cc index e7b7c14..648452c 100644 --- a/gdb/testsuite/gdb.cp/classes.cc +++ b/gdb/testsuite/gdb.cp/classes.cc @@ -434,6 +434,24 @@ Foo::operator int() { return x; } ByAnyOtherName foo(10, 11); Bar bar(20, 21, 22); +/* Use a typedef for the baseclass to exercise gnu-v3-abi.c:gnuv3_dynamic_class + recursion. It's important that the class itself have no name to make sure + the typedef makes it through to the recursive call. */ +typedef class { + public: + int x; + virtual int get_x () { return x; } +} DynamicBase2; + +class DynamicBar : public DynamicBase2 +{ + public: + DynamicBar (int i, int j) { x = i; y = j; } + int y; +}; + +DynamicBar dynbar (23, 24); + class ClassWithEnum { public: enum PrivEnum { red, green, blue, yellow = 42 }; diff --git a/gdb/testsuite/gdb.cp/classes.exp b/gdb/testsuite/gdb.cp/classes.exp index 7b658d5..1d714d3 100644 --- a/gdb/testsuite/gdb.cp/classes.exp +++ b/gdb/testsuite/gdb.cp/classes.exp @@ -307,6 +307,15 @@ proc test_ptype_class_objects {} { { method public "Bar(int, int, int);" } } + # Derived class with typedef'd baseclass with virtual methods. + + cp_test_ptype_class \ + "class DynamicBar" "" "class" "DynamicBar" \ + { + { base "public DynamicBase2" } + { field public "int y;" } + { method public "DynamicBar(int, int);" } + } } # Test simple access to class members. -- 2.7.4