public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "armagvvg at gmail dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/113117] New: ambiguous call during operator overloading is not detected for templates
Date: Fri, 22 Dec 2023 17:59:51 +0000	[thread overview]
Message-ID: <bug-113117-4@http.gcc.gnu.org/bugzilla/> (raw)

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

            Bug ID: 113117
           Summary: ambiguous call during operator overloading is not
                    detected for templates
           Product: gcc
           Version: 13.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: armagvvg at gmail dot com
  Target Milestone: ---

In a nutshell: the next code snippet is compiled successfully, but shouldn't be
according to a language standard:

struct S {
    template <class T>
    S& operator<<(T) { return *this; }
};

template <class T>
T& operator<<(T& s, int) { return s; }

int main () {
    S s;
    s << 1;
}

Details:

Operator overloading for classes can be implemented with free functions and
with class member. When both exist, the C++ standard (I used C++17, part 16.5.2
- Overloaded Operators -> Binary operators) says that "If both forms of the
operator function have been declared, the rules in 16.3.1.2 determine which, if
any, interpretation is used.". The set of candidates contains both the member
and the free function then. The member is considered as a free function with
first implicit parameter (16.3.1 - Candidate functions and argument lists) - "a
member function is considered to have an extra parameter, called the implicit
object parameter, which represents the object for which the member function has
been called".

Thus we have two templates here:
1. template <class T> T& operator<<(T&, int) - defined in the code
2. template <class T> S& operator<<(S, T) - synthesized from the member
function

16.3.3 "Best viable function" mentions that "F1 and F2 are function template
specializations, and the function template for F1 is more specialized than the
template for F2 according to the partial ordering rules described in
17.5.6.2...". But no one template is more specialized for a call "operator<<(S,
int)". Thus we have two best viable functions and "If there is exactly one
viable function that is a better function than all other viable functions, then
it is the
one selected by overload resolution; otherwise the call is ill-formed".

This code snippet should be ill-formed. But it doesn't.

clang detects this as an error.

             reply	other threads:[~2023-12-22 17:59 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-22 17:59 armagvvg at gmail dot com [this message]
2023-12-22 18:02 ` [Bug c++/113117] " pinskia at gcc dot gnu.org
2023-12-22 18:05 ` armagvvg at gmail dot com
2023-12-22 21:23 ` ppalka at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-113117-4@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).