aboutsummaryrefslogtreecommitdiff
path: root/gdb/cp-support.c
diff options
context:
space:
mode:
authorKeith Seitz <keiths@redhat.com>2019-04-25 13:05:51 -0700
committerKeith Seitz <keiths@redhat.com>2019-04-25 13:06:52 -0700
commit725cbb63263d27e87f5a4f9b73281e7710de53e4 (patch)
tree60962bd09743ddf401e082ceee91b5688d319a61 /gdb/cp-support.c
parent3d1cbb78936fbf2985ffd2ebf074841599ead788 (diff)
downloadgdb-725cbb63263d27e87f5a4f9b73281e7710de53e4.zip
gdb-725cbb63263d27e87f5a4f9b73281e7710de53e4.tar.gz
gdb-725cbb63263d27e87f5a4f9b73281e7710de53e4.tar.bz2
c++/24367: Infinite recursion of typedef substitution
This bug finds another usage where we end up segfaulting while normalizing user input. inspect_type and replace_type recurse, attempting to substitute the "real" symbol name for the typedef name. However, since the both these names are the same, they keep calling each other until the stack overflows. A simple reproducer for it is given by typedef struct foo foo; int qux (foo *f) { return 0; } (gdb) b qux(foo*) Segmentation fault inspect_type already contains some special handling to prevent a similar situation from occurring with namespaces. I wonder, however, whether we need be so pedantic about the exact nature of the substitution. This patch implements this rather more aggressive assumption that these substitutions should be avoided whenever the replacement symbol's name is exactly the same as the one we're trying to substitute. [In the above example, we're trying to substitute the tyepdef named "foo" with the symbol named "foo" (a struct).] gdb/ChangeLog: PR c++/24367 * cp-support.c (inspect_type): Don't attempt substitutions of symbol with the same name. gdb/testsuite/ChangeLog: PR c++/24367 * gdb.cp/meth-typedefs.cc (incomplete_struct) (another_incomplete_struct, test_incomplete): New definitions. (main): Use new definitions. * gdb.cp/meth-typedefs.exp: Add new tests for `test_incomplete' functions.
Diffstat (limited to 'gdb/cp-support.c')
-rw-r--r--gdb/cp-support.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index d02a01d..4afb79a 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -190,10 +190,20 @@ inspect_type (struct demangle_parse_info *info,
/* Get the real type of the typedef. */
type = check_typedef (otype);
- /* If the symbol is a namespace and its type name is no different
+ /* If the symbol name is the same as the original type name,
+ don't substitute. That would cause infinite recursion in
+ symbol lookups, as the typedef symbol is often the first
+ found symbol in the symbol table.
+
+ However, this can happen in a number of situations, such as:
+
+ 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
+ alias and does not need to be substituted.
+
+ If the symbol is typedef and its type name is the same
+ as the symbol's name, e.g., "typedef struct foo foo;". */
+ if (TYPE_NAME (type) != nullptr
&& strcmp (TYPE_NAME (type), name) == 0)
return 0;