https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127096

            Bug ID: 127096
           Summary: [12.2 Regression] Wrong decltype((S::x)) in const
                    member function of unrelated class A
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: arthur.j.odwyer at gmail dot com
  Target Milestone: ---

// https://godbolt.org/z/K951PhahT

template<class> int f();

struct S { int x; };
struct A { int g(); int g() const; };
struct B : S { int g(); int g() const; };

int A::g() { return f<decltype((S::x))>(); }
int A::g() const { return f<decltype((S::x))>(); }

int B::g() { return f<decltype((S::x))>(); }
int B::g() const { return f<decltype((S::x))>(); }


In GCC 12.1 and earlier, `int A::g() const` correctly calls `f<int&>`.
In GCC 12.2 and later, it wrongly calls `f<const int&>`, as if `A::g` were a
member of `S` or a class derived from `S`. That is, `A` starts behaving like
`B`!

The behavior of `A::g()`, `B::g()`, and `B::g() const` are all correct; it's
only `A::g() const` that inappropriately const-qualifies the type of an
unevaluated `S::x`.

The standard wording that makes this snippet (surprisingly) legal C++ is
[expr.prim.id]/4.3 ( https://eel.is/c++draft/expr.prim#id.general-4.3 ).

Reply via email to