https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111440
Bug ID: 111440
Summary: wrong-code for ternary with reference-compatible
arguments
Product: gcc
Version: 13.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: leni536 at gmail dot com
Target Milestone: ---
version: g++ 13.2.0
flags: -std=c++20 -O2 -pedantic-errors
Consider the following code:
```
template <typename T>
void foo();,
bool bar() {
int * ptr = nullptr;
const int * const cptr = nullptr;
decltype(auto) res = true ? ptr : cptr;
foo<decltype(res)>(); // calls void<int const*>();
return &res == &ptr; // returns false
}
```
https://godbolt.org/z/cW5bxch5K
The observed behavior is described in the code comments.
The expected behavior is that the ternary expression is an lvalue of type
`const int * const` and the result refers to `ptr`.
https://timsong-cpp.github.io/cppwp/n4868/expr.cond#4.1 applies. The target
type is `const int * const&`, E1 is an lvalue of type `int *`.
`int *` is reference-compatible with `const int * const`, as `int**` is
convertible to `const int * const *`.
https://timsong-cpp.github.io/cppwp/n4868/dcl.init.ref#5.1.1 applies, a
reference of type `const int * const&` can be initialized by an lvalue of type
`int*`, and the reference binds directly.
The wording for "reference-compatible" was changed in the resolution of
https://cplusplus.github.io/CWG/issues/2352.html, so earlier standard modes are
probably similarly affected.