Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: Luis Machado <luis.machado@linaro.org>, gdb-patches@sourceware.org
Subject: Re: [PATCH] Reject ambiguous C++ field accesses
Date: Thu, 27 Aug 2020 20:12:16 +0100	[thread overview]
Message-ID: <30604ffc-365f-d580-18fb-3596c74913e8@palves.net> (raw)
In-Reply-To: <b8fb3cfd-12ef-aefb-17d8-d6c999bd114c@linaro.org>

On 8/27/20 7:45 PM, Luis Machado wrote:
> On 8/27/20 3:02 PM, Pedro Alves wrote:
>> The gdb.cp/ambiguous.exp testcase had been disabled for many years,
>> but recently it was re-enabled.  However, it is failing everywhere.
>> That is because it is testing an old feature that is gone from GDB.
>>
>> The testcase is expecting to see an ambiguous field warning, like:
>>
>>   # X is derived from A1 and A2; both A1 and A2 have a member 'x'
>>   send_gdb "print x.x\n"
>>   gdb_expect {
>>      -re "warning: x ambiguous; using X::A2::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
>>     pass "print x.x"
>>      }
>>      -re "warning: x ambiguous; using X::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
>>     pass "print x.x"
>>      }
>>      -re ".*$gdb_prompt $" { fail "print x.x" }
>>      timeout { fail "(timeout) print x.x" }
>>    }
>>
>> However, GDB just accesses one of the candidates without warning or
>> error:
>>
>>   print x.x
>>   $1 = 1431655296
>>   (gdb) FAIL: gdb.cp/ambiguous.exp: print x.x
>>
>> (The weird number is because the testcase does not initialize the
>> variables.)
>>
>> The testcase come in originally with the big HP merge:
>>
>>   +Sun Jan 10 23:44:11 1999  David Taylor  <taylor@texas.cygnus.com>
>>   +
>>   +
>>   +       The following files are part of the HP merge; some had longer
>>   +       names at HP, but have been renamed to be no more than 14
>>   +       characters in length.
>>
>> Looking at the tree back then, we find that warning:
>>
>>   /* Helper function used by value_struct_elt to recurse through baseclasses.
>>      Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes,
>>      and search in it assuming it has (class) type TYPE.
>>      If found, return value, else return NULL.
>>
>>      If LOOKING_FOR_BASECLASS, then instead of looking for struct fields,
>>      look for a baseclass named NAME.  */
>>
>>   static value_ptr
>>   search_struct_field (name, arg1, offset, type, looking_for_baseclass)
>>        char *name;
>>        register value_ptr arg1;
>>        int offset;
>>        register struct type *type;
>>        int looking_for_baseclass;
>>   {
>>     int found = 0;
>>     char found_class[1024];
>>     value_ptr v;
>>     struct type *vbase = NULL;
>>
>>     found_class[0] = '\000';
>>
>>     v = search_struct_field_aux (name, arg1, offset, type, looking_for_baseclass, &found, found_class, &vbase);
>>     if (found > 1)
>>       warning ("%s ambiguous; using %s::%s. Use a cast to disambiguate.",
>>                name, found_class, name);
>>
>>     return v;
>>   }
>>
>>
>> However, in current GDB, search_struct_field does not handle the
>> ambiguous field case, nor is that warning found anywhere.  Somehow it
>> got lost over the years.  That seems like a regression, because the
>> compiler (as per language rules) rejects the ambiguous accesses as
>> well.  E.g.:
>>
>>   gdb.cp/ambiguous.cc:98:5: error: request for member 'x' is ambiguous
>>      98 |   x.x = 1;
>>         |     ^
>>   gdb.cp/ambiguous.cc:10:7: note: candidates are: 'int A2::x'
>>      10 |   int x;
>>         |       ^
>>   gdb.cp/ambiguous.cc:4:7: note:                 'int A1::x'
>>       4 |   int x;
>>         |       ^
>>
>>
>> This patch restores the feature, though implemented differently and
>> with better user experience, IMHO.  An ambiguous access is now an
>> error instead of a warning, and also GDB shows you the all candidates,
>> like:
>>
>>   (gdb) print x.x
>>   Request for member 'x' is ambiguous in type 'X'. Candidates are:
>>     'int A1::x' (X -> A1)
>>     'int A2::x' (X -> A2)
>>   (gdb) print j.x
>>   Request for member 'x' is ambiguous in type 'J'. Candidates are:
>>     'int A1::x' (J -> K -> A1)
>>     'int A1::x' (J -> L -> A1)
> 
> Would it make sense to spare the users the touble of having to re-type/cast things and, instead, display all the possible values with an indication of what the fields are for each value?
> 
> That would be more intuitive to me, given the debugger is only inspecting things and not enforcing a particular syntax for a source file.
> 
> Users tend to be lazy. They just want to see values, not be syntactically correct. :-)
> 

No, that would not work with not-as-simple expressions.  Like "p foo(x.x + 2)".


  reply	other threads:[~2020-08-27 19:12 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-27 18:02 Pedro Alves
2020-08-27 18:45 ` Luis Machado
2020-08-27 19:12   ` Pedro Alves [this message]
2020-08-27 19:58 ` Luis Machado
2020-08-28 14:35   ` Gary Benson
2020-08-28 20:22     ` [PATCH v2] " Pedro Alves
2020-10-12 17:12       ` Pedro Alves
2020-10-13  8:47         ` Gary Benson via Gdb-patches
2020-08-28 20:12   ` [PATCH] " Pedro Alves
2020-08-28 14:38 ` Gary Benson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=30604ffc-365f-d580-18fb-3596c74913e8@palves.net \
    --to=pedro@palves.net \
    --cc=gdb-patches@sourceware.org \
    --cc=luis.machado@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox