Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Expression parser doesn't use the dynamic type of objects during parsing #35424

Open Quuxplusone opened 6 years ago

Quuxplusone commented 6 years ago
Bugzilla Link PR36451
Status NEW
Importance P enhancement
Reported by Dmitry Antipov (dmantipov@yandex.ru)
Reported on 2018-02-20 04:11:20 -0800
Last modified on 2018-02-20 08:53:00 -0800
Version 6.0
Hardware PC Linux
CC jingham@apple.com, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Test program...

class T0
{
protected:
  int x, y;
public:
  T0 (int a, int b) { x = a, y = b; }
  virtual int func (void) { return x + y; }
  int oops (void) { return x - y; }
};

class T1: public T0
{
public:
  T1 (int a, int b) : T0 (a, b) {}
  virtual int func (void) { return x + y + 1; }
};

class T2: public T1
{
  int z;
public:
  T2 (int a, int b) : T1 (a, b) { z = 111; }
  virtual int func (void) { return x + y + z + 2; }
};

int
main (int argc, char *argv[])
{
  T2 t (1, 2);
  return t.func () + t.oops ();
}

... in LLDB:

$ /home/dantipov/.local/llvm-6.0.0/bin/lldb t-class
(lldb) target create "t-class"
Current executable set to 't-class' (x86_64).
(lldb) b T0::oops
Breakpoint 1: where = t-class`T0::oops() at t-class.cc:8, address =
0x000000000040069c
(lldb) run
Process 8743 launched: '/home/dantipov/tmp/t-class' (x86_64)
Process 8743 stopped
* thread #1, name = 't-class', stop reason = breakpoint 1.1
    frame #0: 0x000000000040069c t-class`T0::oops(this=0x00007fffffffe1b0) at t-class.cc:8
   5    public:
   6      T0 (int a, int b) { x = a, y = b; }
   7      virtual int func (void) { return x + y; }
-> 8      int oops (void) { return x - y; }
   9    };
   10
   11   class T1: public T0
(lldb) p *this
(T0) $0 = (x = 1, y = 2)                      ;; '*this' is an instance of T0
(lldb) p this
(T2 *) $1 = 0x00007fffffffe1b0                ;; 'this' is a pointer to an
instance of T2, but...
(lldb) p this->x
(int) $4 = 1
(lldb) p this->y
(int) $5 = 2
(lldb) p this->z
error: no member named 'z' in 'T0'            ;; ...if so, where is this->z?
Quuxplusone commented 6 years ago

This is a common source of confusion. The expression parser parses expressions purely "as if executed in the current frame". In T0::oops, "this" is a T0, not a T2 and has no "z".

However, once we've gotten the result of the expression, the ValueObject printer can figure out the dynamic type of the object and print the full dynamic value. You can turn this off if you wish (settings set target.prefer-dynamic-value 0). We had this off by default at first lest it be confusing, but people really liked seeing the dynamic value of the result, so we made the default 1 a long time ago.

It would be great to teach the expression parser to fetch dynamic types when possible, but my guess is that's not going to be an easy thing to do. Anyway, that's the bug here.