[Clang] Unexpected results from __reference_{constructs,converts}_from_temporary (original) (raw)

It seems that the following static_assert's should pass, but Clang currently rejects them (link).

static_assert(!__reference_constructs_from_temporary(void(&&)(), void()), "Normal function is treated as lvalue."); static_assert(!__reference_converts_from_temporary(void(&)(), void()), "Normal function is treated as lvalue."); static_assert(!__reference_constructs_from_temporary(void(&)(), void()), "Normal function is treated as lvalue."); static_assert(!__reference_converts_from_temporary(void(&&)(), void()), "Normal function is treated as lvalue."); static_assert(__reference_constructs_from_temporary(int&&, const int), "const int is adjusted to int"); static_assert(__reference_converts_from_temporary(int&&, const int), "const int is adjusted to int");

This probably doesn't block the library implementation of P2255R2 because workaround can be easily implemented.


Moreover, the results of these traits is a bit unclear to me for the following cases (link):

struct Abstract { virtual void fun() = 0; };

static_assert(__reference_constructs_from_temporary(Abstract&&, Abstract), "The code is so abstract."); static_assert(__reference_converts_from_temporary(Abstract&&, Abstract), "The code is so abstract.");

static_assert(__reference_constructs_from_temporary(int(&&)[], int[]), "Array-of-unknown-bound prvalue?"); static_assert(__reference_converts_from_temporary(int(&&)[], int[]), "Array-of-unknown-bound prvalue?");

It seems that the abstractness of the class should be ignored in the spirit of P0929R2 (so Clang is giving correct results for the Abstract case), but this doesn't seem clear in the current standard wording.

The case for int[] is really weird as there's no prvalue of type T[].

CC @cjdb @cor3ntin @timsong-cpp