This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] Fix c++/14819 (implicit this)


Hi Keith,

while the solution seems pretty tricky (some more comments what each line does
would be helpful) it does not work for 'p B::i' and 'p C::i'.  But these could
be fixed I guess, I did not try to do so.

------------------------------------------------------------------------------
class A {
public:
  int i;
  A(int i_):i(i_) {}
};
class B:public A { public: B():A(1) {} };
class C:public A { public: C():A(2) {} };
class D:public B,public C {
public:
  int f() {
    return B::i + C::i;
    // return i; // error: reference to ‘i’ is ambiguous
    // return A::i; // error: ‘A’ is an ambiguous base of ‘D’
  }
};
D d;
int main() { return d.f(); }
------------------------------------------------------------------------------
(gdb) p B::i
base class 'A' is ambiguous in type 'D'
 - this is bug
(gdb) p C::i
base class 'A' is ambiguous in type 'D'
 - this is bug
(gdb) p A::i
base class 'A' is ambiguous in type 'D'
 - this is correct
(gdb) p i
$1 = 2
 - this seems already filed as:
	ambiguous using reference is not error
	http://sourceware.org/bugzilla/show_bug.cgi?id=11540
------------------------------------------------------------------------------


On Tue, 05 Nov 2013 22:08:58 +0100, Keith Seitz wrote:
> --- a/gdb/valops.c
> +++ b/gdb/valops.c
> @@ -3131,7 +3131,32 @@ value_struct_elt_for_reference (struct type *domain, int offset,
>  	  else if (noside == EVAL_AVOID_SIDE_EFFECTS)
>  	    return allocate_value (TYPE_FIELD_TYPE (t, i));
>  	  else
> -	    error (_("Cannot reference non-static field \"%s\""), name);
> +	    {
> +	      /* Try to evaluate NAME as a qualified name with implicit
> +		 this pointer.  In this case, attempt to return the
> +		 equivalent to `this->*(&TYPE::NAME)'.  */
> +	      v = value_of_this_silent (current_language);
> +	      if (v != NULL)
> +		{
> +		  struct value *ptr;
> +		  long mem_offset;

LONGEST, it is returned by value_as_long.

> +		  struct type *type, *tmp;
> +
> +		  ptr = value_aggregate_elt (t, name, NULL, 1, noside);

I cannot reproduce it but I find it a bit fragile, value_aggregate_elt can
return NULL (although it probably would not get here in such case).
At least gdb_assert would be good.


> +		  type = check_typedef (value_type (ptr));
> +		  gdb_assert (type != NULL
> +			      && TYPE_CODE (type) == TYPE_CODE_MEMBERPTR);
> +		  tmp = lookup_pointer_type (TYPE_DOMAIN_TYPE (type));
> +		  v = value_cast_pointers (tmp, v, 1);
> +		  mem_offset = value_as_long (ptr);
> +		  tmp = lookup_pointer_type (TYPE_TARGET_TYPE (type));
> +		  result = value_from_pointer (tmp,
> +					       value_as_long (v) + mem_offset);
> +		  return value_ind (result);
> +		}
> +
> +	      error (_("Cannot reference non-static field \"%s\""), name);
> +	    }
>  	}
>      }


Thanks,
Jan


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]