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

            Bug ID: 110291
           Summary: [11.1 Regression] constraint on friend operator
                    template causes bizarre duplication of RHS template
                    parameter that is passed to the requires expression
           Product: gcc
           Version: 11.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: waffl3x at protonmail dot com
  Target Milestone: ---

template<typename L, typename R>
struct fn { using type = decltype(L{} + R{}); };

struct no_self {};
no_self operator+(int, no_self);

void operator+(no_self, no_self) = delete;

template<typename T>
struct expr {
    template<typename U>
        requires requires {typename fn<T, U>::type;}
    friend void operator/(expr<T>, expr<U>);
};

using X = decltype(expr<int>{} / expr<no_self>{});

https://godbolt.org/z/on1KdfY9T
`error: use of deleted function 'void operator+(no_self, no_self)'`
Working in GCC 9.5 and GCC 10.4, broken in 11.1 and onward. Not too much of a
monologue from me this time, I couldn't beat much interesting information out
of it. Best I can tell is it's definitely related to the constraint (note that
separating it into a concept does not fix the issue), and it being a friend
operator is relevant. I am pretty sure the addition operator overload is not
related, it's just related to what I was doing when I encountered the bug. I'm
pretty sure there is another layer that could be peeled off here, but it
started to hurt my head and for a small bug I think this should be good enough.

It almost seems like it's caching U and preemptively evaluating the RHS as a
LHS with the cached U type. I wanted to confirm this somehow, but like I said,
it just wasn't cooperating. My experimenting was just resulting in much much
more complicated examples,so I decided to just call it here.

Reply via email to