On 11/17/23 16:46, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
-- >8 --
This patch is an attempt to implement (part of?) P2280, Using unknown
pointers and references in constant expressions. (Note that R4 seems to
only allow References to unknown/Accesses via this, but not Pointers to
unknown.)
Indeed. That seems a bit arbitrary to me, but there it is.
We were rejecting the testcase before because
cxx_bind_parameters_in_call was trying to perform an lvalue->rvalue
conversion on the reference itself; this isn't really a thing in the
language, but worked to implement the reference bullet that the paper
removes. Your approach to fixing that makes sense to me.
We should do the same for VAR_DECL references, e.g.
extern int (&r)[42];
constexpr int i = array_size (r);
You also need to allow (implict or explicit) use of 'this', as in:
struct A
{
constexpr int f() { return 42; }
void g() { constexpr int i = f(); }
};
This patch works to the extent that the test case added in [expr.const]
works as expected, as well as the test in
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2280r4.html#the-this-pointer>
Most importantly, the proposal makes this compile:
template <typename T, size_t N>
constexpr auto array_size(T (&)[N]) -> size_t {
return N;
}
void check(int const (¶m)[3]) {
constexpr auto s = array_size(param);
static_assert (s == 3);
}
and I think it would be a pity not to have it in GCC 14.
What still doesn't work (and I don't know if it should) is the test in $3.2:
struct A2 { constexpr int f() { return 0; } };
struct B2 : virtual A2 {};
void f2(B2 &b) { constexpr int k = b.f(); }
where we say
error: '* & b' is not a constant expression
It seems like that is supposed to work, the problem is accessing the
vtable to perform the conversion. I have WIP to recognize that
conversion better in order to fix PR53288; this testcase can wait for
that fix.
Jason