On 4/8/20 7:49 PM, Patrick Palka wrote:
When evaluating the initializer of 'a' in the following example

   struct A { A *p = this; };
   constexpr A foo() { return {}; }
   constexpr A a = foo();

the PLACEHOLDER_EXPR for 'this' in the aggregate initializer returned by foo
gets resolved to the RESULT_DECL of foo.  But due to guaranteed RVO, the 'this'
should really be resolved to '&a'.

It seems to me that the right approach would be to immediately resolve the
PLACEHOLDER_EXPR to the correct target object during evaluation of 'foo()', so
that we could use 'this' to access objects adjacent to the current object in the
ultimate storage location.  (I think #c2 of PR c++/94537 is an example of such
usage of 'this', which currently doesn't work.  But as #c1 shows we don't seem
to handle this case correctly in non-constexpr initialization either.)

As I commented in the PR, the standard doesn't require this to work because A is trivially copyable, and our ABI makes it impossible. But there's still a constexpr bug when we add

A() = default; A(const A&);

clang doesn't require the constructors to make this work for constant initialization, but similarly can't make it work for non-constant initialization.

I haven't yet been able to make a solution using the above approach work --
making sure we use the ultimate object instead of the RESULT_DECL whenever we
access ctx->global->values is proving to be tricky and subtle.

Do we need to go through ctx->global->values? Would it work for the RESULT_DECL case in cxx_eval_constant_expression to go to straight to ctx->object or ctx->ctor instead?

Jason

Reply via email to