| Issue |
114344
|
| Summary |
[Clang] Unexpected results from `__reference_{constructs,converts}_from_temporary`
|
| Labels |
question,
clang:frontend
|
| Assignees |
|
| Reporter |
frederick-vs-ja
|
It seems that the following `static_assert`'s should pass, but Clang currently rejects them ([link](https://www.godbolt.org/z/7Wec34cnT)).
```C++
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");
```
- Per [[expr.type]/2](https://eel.is/c++draft/expr.type#2), "`const int` prvalue" needs to be adjusted to "`int` prvalue", so there shouldn't be cv-qualification dropping and the binding to temporary object should be valid.
- For the (normal) function case, as `decltype(std::declval<Fun>())` is `Fun&` when `Fun` is a normal function type, the reference binding should be valid. But despite the binding being valid or not, there can never be a temporary and thus the traits should report `false`.
This probably doesn't block the library implementation of [P2255R2](https://wg21.lin/p2255r2) because workaround can be easily implemented.
----
Moreover, the results of these traits is a bit unclear to me for the following cases ([link](https://www.godbolt.org/z/jqrM3hvWP)):
```C++
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](https://wg21.link/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
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs