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.