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.

Reply via email to