Compare commits

...

1 Commits

Author SHA1 Message Date
Simon Marchi
e61b4af73d Don't trust templates from DW_AT_name
With gcc 8 (and clang?) the non-type template arguments (constants)
don't include the integer suffixes anymore.  For example, with

  template <unsigned int X>
  class foo
  {
    ...
  };

  foo<10u>

used to generate foo<10u> as the DW_AT_name, now it generates foo<10>.
This is a problem when things look up "foo<10u>" and don't find it.  For
example, when trying to print an instance of that class through a base
class pointer, GDB would first demangle the symbol for that class'
vtable, which would give "vtable for foo<10u>".  GDB would then take the
"foo<10u>" from that string and try to look up the type.  With the new
DW_AT_name, it would fail to look it up, and fail to print the value.

This patch makes it so GDB doesn't trust the templates contained in
DW_AT_name.  Instead, it re-builds the name from the DW_AT_template_*
DIES in the format that it expects (with the integer suffixes).
2018-02-04 22:21:08 -05:00
4 changed files with 40 additions and 3 deletions

View File

@@ -454,6 +454,21 @@ c_val_print_int (struct type *type, struct type *unresolved_type,
: options->output_format);
val_print_scalar_formatted (type, embedded_offset,
original_value, &opts, 0, stream);
if (opts.print_suffix)
{
struct type *t = check_typedef (type);
if (TYPE_UNSIGNED (t))
fputc_filtered ('u', stream);
/* Is there a better way to do this? Just looking at the size doesn't
work. */
if (strstr (TYPE_NAME (t), "long long") != NULL)
fputs_filtered ("ll", stream);
else if (strstr (TYPE_NAME (t), "long") != NULL)
fputc_filtered ('l', stream);
}
}
else
{

View File

@@ -9211,7 +9211,7 @@ partial_die_full_name (struct partial_die_info *pdi,
{
fixup_partial_die (pdi, cu);
if (pdi->name != NULL && strchr (pdi->name, '<') == NULL)
if (pdi->name != NULL)
{
struct die_info *die;
struct attribute attr;
@@ -10875,6 +10875,22 @@ dwarf2_compute_name (const char *name,
if (name == NULL)
name = dwarf2_name (die, cu);
/* If there is a template in the name, strip it and let the code below
re-compute it. */
gdb::unique_xmalloc_ptr<char> holder;
if (name != NULL)
{
const char *opening = strchr (name, '<');
if (opening != NULL)
{
/* In this case, name will get copied/modified and re-assigned,
so we can free this copy. */
holder.reset (xstrdup (name));
holder.get ()[opening - name] = '\0';
name = holder.get ();
}
}
/* For Fortran GDB prefers DW_AT_*linkage_name for the physname if present
but otherwise compute it by typename_concat inside GDB.
FIXME: Actually this is not really true, or at least not always true.
@@ -10942,7 +10958,7 @@ dwarf2_compute_name (const char *name,
templates; two instantiated function templates are allowed to
differ only by their return types, which we do not add here. */
if (cu->language == language_cplus && strchr (name, '<') == NULL)
if (cu->language == language_cplus)
{
struct attribute *attr;
struct die_info *child;
@@ -11026,6 +11042,7 @@ dwarf2_compute_name (const char *name,
the radix. */
get_formatted_print_options (&opts, 'd');
opts.raw = 1;
opts.print_suffix = true;
value_print (v, &buf, &opts);
release_value (v);
value_free (v);

View File

@@ -109,7 +109,8 @@ struct value_print_options user_print_options =
1, /* pascal_static_field_print */
0, /* raw */
0, /* summary */
1 /* symbol_print */
1, /* symbol_print */
false, /* print_suffix */
};
/* Initialize *OPTS to be a copy of the user print options. */

View File

@@ -92,6 +92,10 @@ struct value_print_options
/* If nonzero, when printing a pointer, print the symbol to which it
points, if any. */
int symbol_print;
/* If true, print the integer suffixes (u for unsigned, l for long, ll for
long long). */
bool print_suffix;
};
/* The global print options set by the user. In general this should