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