From patchwork Fri Oct 27 19:55:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 159144 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:d641:0:b0:403:3b70:6f57 with SMTP id cy1csp852453vqb; Fri, 27 Oct 2023 13:02:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGosAW9vTWdWK1FD+mVVaMIvGXQAswMSaj2pOkKva/nnj1Xv4Tajxfwp0rfvkzpUslGHA+6 X-Received: by 2002:a1f:2f86:0:b0:4a0:6fd4:4333 with SMTP id v128-20020a1f2f86000000b004a06fd44333mr4212686vkv.13.1698436921417; Fri, 27 Oct 2023 13:02:01 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1698436921; cv=pass; d=google.com; s=arc-20160816; b=PofT2Lsrj98MIEFISz60k+t7VInoKzR48LaatuUhXWMtAHsLJ4aW7ULZRTq08etXm+ mH1s781GP2ZFdmN5BhrwHlsALnVOzTYxyKCxAxx+xOgbOp4eBCjtgwmYW2wMRNVFsXIc oMG15GNJsMR4zDt2mCbsp59SgYIqtLk/FfOqWp3tWVCyiMZy+HJimpYHcfBWAbvtCSkZ rfAFT/vALxsL8PgEuygw5CdCcKJ4CHZcp9fLVcFVXSTofHiffFiknOlB+ZyTa+JZyMBl kVtkES+RIOKwzZAaux5ZtqseuqIz+6KBIqqDci1hWV1ihaA2JrzrRiR+kNudy+sfRubv pzZg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature :arc-filter:dmarc-filter:delivered-to; bh=cIv0OgmG0aQfexfv/Qbapm8c1yGfJNql2aeIKbvGQBk=; fh=1Hi9m88IqcWZGtfSxUrMGG+GBgL26N02X1SANXM6iTs=; b=QZQDii8HIdhh27HHsqOtCPeE5Hi6Y0o8sxDNNP4VvkD5Cp1sfhYfGrdJmcekj6OBBZ MjWTUq0zJlsylKogHMa+chTyLLucd/S9JKperfMOwIwZDDEg/G5ak1k1ytEIcb9Vm/dM T1uUL8NElZh4qNLeJFmYhF1UfOC78tiJ1cISNao1xq22IrESQQ4yomLVhEpzG5/yI+by 7UMKO1wvRdVDCimkpgPQHoFl3gR+0WcFleMzqmqpCXFTtCR6MQh9ojnmlFiA2PgAZ7rz aTaRwyP3yQpnx8LG4hyjpYkhxMF4rTRpoCOoIPnzOFnzggNQZtoib6ngTVZLlHI0NAO7 jgbw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=AH16Dwwk; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id w67-20020a1fc646000000b0049d6bd9c98dsi362121vkf.293.2023.10.27.13.02.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Oct 2023 13:02:01 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=AH16Dwwk; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8CDBA3831E3B for ; Fri, 27 Oct 2023 20:01:50 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 7649938618EE for ; Fri, 27 Oct 2023 20:01:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7649938618EE Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7649938618EE Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698436885; cv=none; b=C0lZBwfAKxHcOBX+0VIG+Y0KnsE5VGzeXsTRhxUt40UlNR+uyAOJZVM7qEmjgMHbF2a84KwP8Nc7PIDjOA9QXNl2SmJP9ihrcRrw4DV6bkCBSmniXw81vsjg2ifrELWfXCRVFu25grnI5dKmc+Yxx9ieUTanOxnBpHZRKsCjIr8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698436885; c=relaxed/simple; bh=GWtJipD6Hla5dVEVj1ZUSehRr8vyNawZvsg1DkmkCUg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=sk/sOwPFOhEiWkaz+tdRMDr1OL+WuInavbZAkbp6DkWAArC9bjEXstwMI9QA+FfH/HTxuCgapg0jPAwB/EzF8Dh5Hb/QyAZZQ0Xu+qMMOmszH36D+pv2z/vu/lXOdngCUgcv5RhYhn8msiHpmAUlpqYyvnUc+fy1wBXFiCp83p0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1698436883; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cIv0OgmG0aQfexfv/Qbapm8c1yGfJNql2aeIKbvGQBk=; b=AH16DwwkFW5G7zqNDTwNZ/afaS6liBU/ueLslStDHzWqonUaNPhTBWW4Xp+AF8E3LWO019 zL9XeXJuQ7S5uEFdiO/xt45E5y1W3P//nZ8Q92dZfq4uZFFloNJUl+aCfzwmaGRSB5zHdR /5CDc+d5R40FznSFdAlrCrmZi/FNY2Y= Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-315-YRR-sc_pP_mb-TlJCO8MsQ-1; Fri, 27 Oct 2023 16:01:12 -0400 X-MC-Unique: YRR-sc_pP_mb-TlJCO8MsQ-1 Received: by mail-qv1-f71.google.com with SMTP id 6a1803df08f44-66d062708b0so34344496d6.1 for ; Fri, 27 Oct 2023 13:01:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698436871; x=1699041671; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=cIv0OgmG0aQfexfv/Qbapm8c1yGfJNql2aeIKbvGQBk=; b=SXsoFbdtK4tn8cC5R/ThUz20AfTD9pUX8nf716Y2VFTL+oWxIlOTJlQ9iWpSJiZQDq UWbds6PDRfqBu7pTBMW6WJoaf8A6FpaunTy1Dex7DjdL/09Ed/Xv2WLZJvi/JKO2mcg4 s9uC07lmMxQEhENX8RPhVsDyAdUhIH8+4+gl/pYvNJbaXxkkxWR4hA3kCYmYSmAkfyM0 STj+KWKHdoHqdyLY6EqP95h2MOW9K3ArmRwc3XThm3rEnXf7nIvobMEjrZjoLvVJ3stK ssqkVEoL6Y7sncqsfI1x7DClmuLi9B3wvytVfT2PMCo5Tm3m6gTEFUhfLfSuuMEMdsqH z5Pw== X-Gm-Message-State: AOJu0Yx2Z7hxbFg2edfUWh3FENBYpBG2IeTkdPD645FsHA8yV1RD0ZgE 7zOeGc7xCrpfYO7SjnQkOo9jLB/e4MuEMS2SNNS1FOCGEg1udatLmmEBdgxhf/N9nMuDEQGDhHN I+X4L48MxSxifGJ58yqKm+oEbehW5eZvbPqZQmR/T9h1BaJZRTsOZjAWw5iO8ntHAsWujrLPqeh I= X-Received: by 2002:a05:6214:2468:b0:66d:11e7:d4fe with SMTP id im8-20020a056214246800b0066d11e7d4femr5802943qvb.40.1698436870933; Fri, 27 Oct 2023 13:01:10 -0700 (PDT) X-Received: by 2002:a05:6214:2468:b0:66d:11e7:d4fe with SMTP id im8-20020a056214246800b0066d11e7d4femr5802894qvb.40.1698436870443; Fri, 27 Oct 2023 13:01:10 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id l20-20020a0ce514000000b0065b17b925d0sm910777qvm.38.2023.10.27.13.01.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Oct 2023 13:01:09 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH v3 1/3] c++: sort candidates according to viability Date: Fri, 27 Oct 2023 15:55:29 -0400 Message-ID: <20231027195532.2566822-1-ppalka@redhat.com> X-Mailer: git-send-email 2.42.0.482.g2e8e77cbac MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780940193606683142 X-GMAIL-MSGID: 1780940193606683142 New in patch 1/3: * consistently use "non-viable" instead of "unviable" throughout * make 'champ' and 'challenger' in 'tourney' be z_candidate** to simplify moving 'champ' to the front of the list. drive-by cleanups in tourney, including renaming 'champ_compared_to_predecessor' to 'previous_worse_champ' for clarity. New in patch 2/3: * consistently use "non-viable" instead of "unviable" throughout New in patch 3/3: * introduce new -fnote-all-cands flag that controls noting other candidates when diagnosing deletedness, and also controls noting "ignored" candidates in general. -- >8 -- This patch: * changes splice_viable to move the non-viable candidates to the end of the list instead of removing them outright * makes tourney move the best candidate to the front of the candidate list * adjusts print_z_candidates to preserve our behavior of printing only viable candidates when diagnosing ambiguity * adds a parameter to print_z_candidates to control this default behavior (the follow-up patch will want to print all candidates when diagnosing deletedness) Thus after this patch we have access to the entire candidate list through the best viable candidate. This change also happens to fix diagnostics for the below testcase where we currently neglect to note the third candidate, since the presence of the two unordered non-strictly viable candidates causes splice_viable to prematurely get rid of the non-viable third candidate. gcc/cp/ChangeLog: * call.cc: Include "tristate.h". (splice_viable): Sort the candidate list according to viability. Don't remove non-viable candidates from the list. (print_z_candidates): Add defaulted only_viable_p parameter. By default only print non-viable candidates if there is no viable candidate. (tourney): Make 'candidates' parameter a reference. Ignore non-viable candidates. Move the true champ to the front of the candidates list, and update 'candidates' to point to the front. Drive-by cleanups, including renaming 'champ_compared_to_predecessor' to 'previous_worse_champ'. gcc/testsuite/ChangeLog: * g++.dg/overload/error5.C: New test. --- gcc/cp/call.cc | 181 ++++++++++++++----------- gcc/testsuite/g++.dg/overload/error5.C | 12 ++ 2 files changed, 117 insertions(+), 76 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/error5.C diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 2eb54b5b6ed..5d175b93a47 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "decl.h" #include "gcc-rich-location.h" +#include "tristate.h" /* The various kinds of conversion. */ @@ -160,7 +161,7 @@ static struct obstack conversion_obstack; static bool conversion_obstack_initialized; struct rejection_reason; -static struct z_candidate * tourney (struct z_candidate *, tsubst_flags_t); +static struct z_candidate * tourney (struct z_candidate *&, tsubst_flags_t); static int equal_functions (tree, tree); static int joust (struct z_candidate *, struct z_candidate *, bool, tsubst_flags_t); @@ -176,7 +177,8 @@ static void op_error (const op_location_t &, enum tree_code, enum tree_code, static struct z_candidate *build_user_type_conversion_1 (tree, tree, int, tsubst_flags_t); static void print_z_candidate (location_t, const char *, struct z_candidate *); -static void print_z_candidates (location_t, struct z_candidate *); +static void print_z_candidates (location_t, struct z_candidate *, + tristate = tristate::unknown ()); static tree build_this (tree); static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *); static bool any_strictly_viable (struct z_candidate *); @@ -3700,68 +3702,60 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl, } /* The CANDS are the set of candidates that were considered for - overload resolution. Return the set of viable candidates, or CANDS - if none are viable. If any of the candidates were viable, set + overload resolution. Sort CANDS so that the strictly viable + candidates appear first, followed by non-strictly viable candidates, + followed by non-viable candidates. Returns the first candidate + in this sorted list. If any of the candidates were viable, set *ANY_VIABLE_P to true. STRICT_P is true if a candidate should be - considered viable only if it is strictly viable. */ + considered viable only if it is strictly viable when setting + *ANY_VIABLE_P. */ static struct z_candidate* splice_viable (struct z_candidate *cands, bool strict_p, bool *any_viable_p) { - struct z_candidate *viable; - struct z_candidate **last_viable; - struct z_candidate **cand; - bool found_strictly_viable = false; + z_candidate *strictly_viable = nullptr; + z_candidate **strictly_viable_tail = &strictly_viable; + + z_candidate *non_strictly_viable = nullptr; + z_candidate **non_strictly_viable_tail = &non_strictly_viable; + + z_candidate *non_viable = nullptr; + z_candidate **non_viable_tail = &non_viable; /* Be strict inside templates, since build_over_call won't actually do the conversions to get pedwarns. */ if (processing_template_decl) strict_p = true; - viable = NULL; - last_viable = &viable; - *any_viable_p = false; - - cand = &cands; - while (*cand) + for (z_candidate *cand = cands; cand; cand = cand->next) { - struct z_candidate *c = *cand; if (!strict_p - && (c->viable == 1 || TREE_CODE (c->fn) == TEMPLATE_DECL)) - { - /* Be strict in the presence of a viable candidate. Also if - there are template candidates, so that we get deduction errors - for them instead of silently preferring a bad conversion. */ - strict_p = true; - if (viable && !found_strictly_viable) - { - /* Put any spliced near matches back onto the main list so - that we see them if there is no strict match. */ - *any_viable_p = false; - *last_viable = cands; - cands = viable; - viable = NULL; - last_viable = &viable; - } - } + && (cand->viable == 1 || TREE_CODE (cand->fn) == TEMPLATE_DECL)) + /* Be strict in the presence of a viable candidate. Also if + there are template candidates, so that we get deduction errors + for them instead of silently preferring a bad conversion. */ + strict_p = true; - if (strict_p ? c->viable == 1 : c->viable) - { - *last_viable = c; - *cand = c->next; - c->next = NULL; - last_viable = &c->next; - *any_viable_p = true; - if (c->viable == 1) - found_strictly_viable = true; - } - else - cand = &c->next; + /* Move this candidate to the appropriate list according to + its viability. */ + auto& tail = (cand->viable == 1 ? strictly_viable_tail + : cand->viable == -1 ? non_strictly_viable_tail + : non_viable_tail); + *tail = cand; + tail = &cand->next; } - return viable ? viable : cands; + *any_viable_p = (strictly_viable != nullptr + || (!strict_p && non_strictly_viable != nullptr)); + + /* Combine the lists. */ + *non_viable_tail = nullptr; + *non_strictly_viable_tail = non_viable; + *strictly_viable_tail = non_strictly_viable; + + return strictly_viable; } static bool @@ -3995,8 +3989,13 @@ print_z_candidate (location_t loc, const char *msgstr, } } +/* Print information about each overload candidate in CANDIDATES, + which is assumed to have gone through splice_viable and tourney + (if splice_viable succeeded). */ + static void -print_z_candidates (location_t loc, struct z_candidate *candidates) +print_z_candidates (location_t loc, struct z_candidate *candidates, + tristate only_viable_p /* = tristate::unknown () */) { struct z_candidate *cand1; struct z_candidate **cand2; @@ -4041,8 +4040,19 @@ print_z_candidates (location_t loc, struct z_candidate *candidates) } } + /* Unless otherwise specified, if there's a (strictly) viable candidate + then we assume we're being called as part of diagnosing ambiguity, in + which case we want to print only viable candidates since non-viable + candidates couldn't have contributed to the ambiguity. */ + if (only_viable_p.is_unknown ()) + only_viable_p = candidates->viable == 1; + for (; candidates; candidates = candidates->next) - print_z_candidate (loc, N_("candidate:"), candidates); + { + if (only_viable_p.is_true () && candidates->viable != 1) + break; + print_z_candidate (loc, N_("candidate:"), candidates); + } } /* USER_SEQ is a user-defined conversion sequence, beginning with a @@ -13169,57 +13179,76 @@ tweak: /* Given a list of candidates for overloading, find the best one, if any. This algorithm has a worst case of O(2n) (winner is last), and a best case of O(n/2) (totally ambiguous); much better than a sorting - algorithm. */ + algorithm. The candidates list is assumed to be sorted according + to viability (via splice_viable). */ static struct z_candidate * -tourney (struct z_candidate *candidates, tsubst_flags_t complain) +tourney (struct z_candidate *&candidates, tsubst_flags_t complain) { - struct z_candidate *champ = candidates, *challenger; + struct z_candidate **champ = &candidates, **challenger; int fate; - struct z_candidate *champ_compared_to_predecessor = nullptr; + struct z_candidate *previous_worse_champ = nullptr; /* Walk through the list once, comparing each current champ to the next candidate, knocking out a candidate or two with each comparison. */ - for (challenger = champ->next; challenger; ) + for (challenger = &candidates->next; *challenger && (*challenger)->viable; ) { - fate = joust (champ, challenger, 0, complain); + fate = joust (*champ, *challenger, 0, complain); if (fate == 1) - challenger = challenger->next; + challenger = &(*challenger)->next; + else if (fate == -1) + { + previous_worse_champ = *champ; + champ = challenger; + challenger = &(*challenger)->next; + } else { - if (fate == 0) + previous_worse_champ = nullptr; + champ = &(*challenger)->next; + if (!*champ || !(*champ)->viable) { - champ = challenger->next; - if (champ == 0) - return NULL; - champ_compared_to_predecessor = nullptr; - } - else - { - champ_compared_to_predecessor = champ; - champ = challenger; + champ = nullptr; + break; } - - challenger = champ->next; + challenger = &(*champ)->next; } } /* Make sure the champ is better than all the candidates it hasn't yet been compared to. */ - for (challenger = candidates; - challenger != champ; - challenger = challenger->next) + if (champ) + for (challenger = &candidates; + challenger != champ; + challenger = &(*challenger)->next) + { + if (*challenger == previous_worse_champ) + /* We already know this candidate this worse than the champ. */ + continue; + fate = joust (*champ, *challenger, 0, complain); + if (fate != 1) + { + champ = nullptr; + break; + } + } + + if (!champ) + return nullptr; + + /* Move the champ to the front of the candidate list. */ + + if (champ != &candidates) { - if (challenger == champ_compared_to_predecessor) - continue; - fate = joust (champ, challenger, 0, complain); - if (fate != 1) - return NULL; + z_candidate *saved_champ = *champ; + *champ = saved_champ->next; + saved_champ->next = candidates; + candidates = saved_champ; } - return champ; + return candidates; } /* Returns nonzero if things of type FROM can be converted to TO. */ diff --git a/gcc/testsuite/g++.dg/overload/error5.C b/gcc/testsuite/g++.dg/overload/error5.C new file mode 100644 index 00000000000..6a2f3b5ba35 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/error5.C @@ -0,0 +1,12 @@ +// Verify we note all three candidates when diagnosing overload +// resolution failure. The presence of the first two (ambiguous) +// non-strictly viable candidates used to make us prune the third +// and not note it. + +void f(int, int*); // { dg-message "candidate" } +void f(int*, int); // { dg-message "candidate" } +void f(int, int, int); // { dg-message "candidate" } + +int main() { + f(1, 2); // { dg-error "no match|invalid conversion" } +} From patchwork Fri Oct 27 19:55:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 159142 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:d641:0:b0:403:3b70:6f57 with SMTP id cy1csp852350vqb; Fri, 27 Oct 2023 13:01:53 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFeLd8R111ZS5oYq/y9MwB2pNVuykzmUTHjU9yxsy6mtyOqpjUk7obSCanEusvm8kVFOVrP X-Received: by 2002:a67:e05a:0:b0:457:c1d2:a0ab with SMTP id n26-20020a67e05a000000b00457c1d2a0abmr3785347vsl.18.1698436913102; Fri, 27 Oct 2023 13:01:53 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1698436913; cv=pass; d=google.com; s=arc-20160816; b=hEPdQUrCDuEkuk0BEmmGqhWn0DYk3e+SEESPXmQVYzJioc8lABflcjD/pgnWjhZgHN uPAXv2AkxEbz71bqfsBZFlynI7T86kzN4fchhUeFhOs29xoqjxNFMhreuDP3yxmqvXbv 144eFApD4NI1nS5WbPw8UXlyz8ck5y+lVESb2zx8Yp7O43Eb5U268sxtH50D2UmaFIPR i9UnolgMIeUsj1jcUPWoxkKQC7KmYqYuEiYfLDz5wLrs1KMwbySJJ+GMYl4T7vkmnCtz gc097eyVWKV0T6mj1uXR7FB9ZRP8GlsunrWuQGbJCu6II6e7qJVU0hpjDogaBIpPsJy1 EhyQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=GAcZooTvCmWdzoOVdyTNYJB8zSbKcMY24Kg43s//kgU=; fh=1Hi9m88IqcWZGtfSxUrMGG+GBgL26N02X1SANXM6iTs=; b=ymqbRpAwpqBZ9kmxYeQU8CRwaBPibR0Xvp/Q+uqzHVBWiO0Hi9rh4iOKSg45ysTpM3 3qQS2ufiVEvMEL2GxsjejyJYEkxzhBXx+pBOQep7JfdDIHGHw0sNTqNEnU/IBUJEaq4p itsHuT+9A084aykru6YxXpwvT+XpDqoiARebtxixOI4Md0NbzGSybVUo6pcp+qQs/ksB YMbhHMERWIIj8LZJ1pLpQMfGV/PA9CVJeQEH0RGWv0ZxS6TNYa0ei/Rh4yPVYMi9fICP o5k6ii2hOjyzkqlM924vhW3oyDBHmEQ9gfUFV8rPgBGvny2ZdDtC4J3OHgW5v/vjEk53 I4WA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=aB3T7l3y; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id h10-20020a056102104a00b00452b20ff998si385560vsq.261.2023.10.27.13.01.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Oct 2023 13:01:53 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=aB3T7l3y; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 78E443875DCD for ; Fri, 27 Oct 2023 20:01:44 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 8FE47385C6C4 for ; Fri, 27 Oct 2023 20:01:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8FE47385C6C4 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 8FE47385C6C4 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698436878; cv=none; b=DwDnpr0zv/x+mSdjfIBnpUm9YrdxYPtM/FCmAQ6jwLZyFUu2myzmpTKjTOP1D0rhvTjYAeUUtUYq41dFFQXd+UQAi/fCPney49VOdYRqz6R3x6n45t8MfyeFpD/gcQDXhif357JI82wO11kKG+b78LN6JEpjZYbsPlfDqFEj+a8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698436878; c=relaxed/simple; bh=PssYKsTuqPoREWhDIhtd//kEO462mDlMON+ST0mtJGo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=meWvv37hzwlNZ3ve0eP1o8yEY5i1LOTTK/OPH7HJoUHnSWkSBml88FRf+RlAH3GtWUubAroPiFfO2/0wkaastj5S7QQZBLwUjnFbucV3T+Jw6bYRfxvlBJwPknNr7AEl1ieOogk0TjJ0Eta86DSBt+3sbiR10QJK1/1QbX2CtJM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1698436876; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GAcZooTvCmWdzoOVdyTNYJB8zSbKcMY24Kg43s//kgU=; b=aB3T7l3y+h1GniboeglhLAN98f2x8m+t5ZLbZEcJo9u/iR+nmzbv7AwiH9o+8FAOeiDc5l BrKAJjXgRtn0I/9unhVHsEWoxQvynlKRkHgQfY8SdC7xF4c7nCNop+AK4GwT/KBmLCBSyf 6eFoDKQta96Y3VlQsny3n4t3rBTEKCU= Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-647-ySViq0o0PG6nM38-hZ7b4A-1; Fri, 27 Oct 2023 16:01:14 -0400 X-MC-Unique: ySViq0o0PG6nM38-hZ7b4A-1 Received: by mail-qv1-f71.google.com with SMTP id 6a1803df08f44-66d062708b0so34345256d6.1 for ; Fri, 27 Oct 2023 13:01:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698436873; x=1699041673; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GAcZooTvCmWdzoOVdyTNYJB8zSbKcMY24Kg43s//kgU=; b=ZMWpgrWAbXtxIe+0fOL+GWVgmUzxlhpEZZSKqWgQ74un9ycXrfoeuWLTmEP99d9AdL j7oWcOf90uxtCuPNe8tWqhycKc818fhWUmAHpzVNNVMnF08Fwi3UZ7nQ6M4zKxvOMHv+ IqburPe95X1ds9W90F0fE2YjXCS/EjIJnWnglTUUH9d8SpSGdSTBAEbiJAx9z+qCyvyJ NoeoZwnrOMh7V0K0H7l8mr8EDc8I80s7/3jlluFaF77wn1yLeVekmMwbG+DRH9Gn7Sx9 6hPGjj2hvVdhzJg483IXsYtUMYvTBwrS65l4wjYqdeBcjtGB4keemiyG/HTAeoI5aAMH bJ0g== X-Gm-Message-State: AOJu0YxFJ2c7olRyG7GsXPwwm4BEqcU2YobZkrYt0ZOZ7CEarWp0XL/r H58L1tOEUWk4NhGz9wcK9EEUqnzxxF9UvQMNvVZD7GU2+kQYk91RX6GQJ73Wq3B1XdVV6VpgJt2 ZdNKiCo5swYwt4CQL7REywwqG0vJxvjHF/YRLWlMWfwcAytPuQZoQMigE3gF1iuox4QrWxKFJuS w= X-Received: by 2002:a05:6214:252a:b0:66d:603b:9a0e with SMTP id gg10-20020a056214252a00b0066d603b9a0emr4226619qvb.16.1698436873393; Fri, 27 Oct 2023 13:01:13 -0700 (PDT) X-Received: by 2002:a05:6214:252a:b0:66d:603b:9a0e with SMTP id gg10-20020a056214252a00b0066d603b9a0emr4226596qvb.16.1698436872950; Fri, 27 Oct 2023 13:01:12 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id l20-20020a0ce514000000b0065b17b925d0sm910777qvm.38.2023.10.27.13.01.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Oct 2023 13:01:12 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH v3 2/3] c++: remember candidates that we ignored Date: Fri, 27 Oct 2023 15:55:30 -0400 Message-ID: <20231027195532.2566822-2-ppalka@redhat.com> X-Mailer: git-send-email 2.42.0.482.g2e8e77cbac In-Reply-To: <20231027195532.2566822-1-ppalka@redhat.com> References: <20231027195532.2566822-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780940184117500871 X-GMAIL-MSGID: 1780940184117500871 During overload resolution, we sometimes outright ignore a function in the overload set and leave no trace of it in the candidates list, for example when we find a perfect non-template candidate we discard all function templates, or when the callee is a template-id we discard all non-template functions. We should still however make note of these non-viable functions when diagnosing overload resolution failure, but that's not possible if they're not present in the returned candidates list. To that end, this patch reworks add_candidates to add such ignored functions to the list. The new rr_ignored rejection reason is somewhat of a catch-all; we could perhaps split it up into more specific rejection reasons, but I leave that as future work. gcc/cp/ChangeLog: * call.cc (enum rejection_reason_code): Add rr_ignored. (add_ignored_candidate): Define. (ignored_candidate_p): Define. (add_template_candidate_real): Do add_ignored_candidate instead of returning NULL. (splice_viable): Put ignored (non-viable) candidates last. (print_z_candidate): Handle ignored candidates. (build_new_function_call): Refine shortcut that calls cp_build_function_call_vec now that non-templates can appear in the candidate list for a template-id call. (add_candidates): Replace 'bad_fns' overload with 'bad_cands' candidate list. When not considering a candidate, add it to the list as an ignored candidate. Add all 'bad_cands' to the overload set as well. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/param-type-mismatch-2.C: Rename template function test_7 that accidentally (perhaps) shares the same name as its non-template callee. * g++.dg/overload/error6.C: New test. --- gcc/cp/call.cc | 150 +++++++++++++----- .../g++.dg/diagnostic/param-type-mismatch-2.C | 20 +-- gcc/testsuite/g++.dg/overload/error6.C | 9 ++ 3 files changed, 133 insertions(+), 46 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/error6.C diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 5d175b93a47..81cc029dddb 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -441,7 +441,8 @@ enum rejection_reason_code { rr_template_unification, rr_invalid_copy, rr_inherited_ctor, - rr_constraint_failure + rr_constraint_failure, + rr_ignored, }; struct conversion_info { @@ -2224,6 +2225,35 @@ add_candidate (struct z_candidate **candidates, return cand; } +/* FN is a function from the overload set that we outright didn't even + consider (for some reason); add it to the list as an non-viable "ignored" + candidate. */ + +static z_candidate * +add_ignored_candidate (z_candidate **candidates, tree fn) +{ + /* No need to dynamically allocate these. */ + static const rejection_reason reason_ignored = { rr_ignored, {} }; + + struct z_candidate *cand = (struct z_candidate *) + conversion_obstack_alloc (sizeof (struct z_candidate)); + + cand->fn = fn; + cand->reason = const_cast (&reason_ignored); + cand->next = *candidates; + *candidates = cand; + + return cand; +} + +/* True iff CAND is a candidate added by add_ignored_candidate. */ + +static bool +ignored_candidate_p (const z_candidate *cand) +{ + return cand->reason && cand->reason->code == rr_ignored; +} + /* Return the number of remaining arguments in the parameter list beginning with ARG. */ @@ -3471,7 +3501,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, } if (len < skip_without_in_chrg) - return NULL; + return add_ignored_candidate (candidates, tmpl); if (DECL_CONSTRUCTOR_P (tmpl) && nargs == 2 && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (first_arg), @@ -3609,7 +3639,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, if (((flags & (LOOKUP_ONLYCONVERTING|LOOKUP_LIST_INIT_CTOR)) == LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (fn)) - return NULL; + return add_ignored_candidate (candidates, fn); if (DECL_CONSTRUCTOR_P (fn) && nargs == 2) { @@ -3724,6 +3754,9 @@ splice_viable (struct z_candidate *cands, z_candidate *non_viable = nullptr; z_candidate **non_viable_tail = &non_viable; + z_candidate *non_viable_ignored = nullptr; + z_candidate **non_viable_ignored_tail = &non_viable_ignored; + /* Be strict inside templates, since build_over_call won't actually do the conversions to get pedwarns. */ if (processing_template_decl) @@ -3742,6 +3775,7 @@ splice_viable (struct z_candidate *cands, its viability. */ auto& tail = (cand->viable == 1 ? strictly_viable_tail : cand->viable == -1 ? non_strictly_viable_tail + : ignored_candidate_p (cand) ? non_viable_ignored_tail : non_viable_tail); *tail = cand; tail = &cand->next; @@ -3751,7 +3785,8 @@ splice_viable (struct z_candidate *cands, || (!strict_p && non_strictly_viable != nullptr)); /* Combine the lists. */ - *non_viable_tail = nullptr; + *non_viable_ignored_tail = nullptr; + *non_viable_tail = non_viable_ignored; *non_strictly_viable_tail = non_viable; *strictly_viable_tail = non_strictly_viable; @@ -3901,6 +3936,8 @@ print_z_candidate (location_t loc, const char *msgstr, inform (cloc, "%s%qT (conversion)", msg, fn); else if (candidate->viable == -1) inform (cloc, "%s%#qD (near match)", msg, fn); + else if (ignored_candidate_p (candidate)) + inform (cloc, "%s%#qD (ignored)", msg, fn); else if (DECL_DELETED_FN (fn)) inform (cloc, "%s%#qD (deleted)", msg, fn); else if (candidate->reversed ()) @@ -3980,6 +4017,8 @@ print_z_candidate (location_t loc, const char *msgstr, "initialization from an expression of the same or derived " "type"); break; + case rr_ignored: + break; case rr_none: default: /* This candidate didn't have any issues or we failed to @@ -5023,7 +5062,12 @@ build_new_function_call (tree fn, vec **args, // If there is a single (non-viable) function candidate, // let the error be diagnosed by cp_build_function_call_vec. if (!any_viable_p && candidates && ! candidates->next - && (TREE_CODE (candidates->fn) == FUNCTION_DECL)) + && TREE_CODE (candidates->fn) == FUNCTION_DECL + /* A template-id callee consisting of a single (ignored) + non-template candidate needs to be diagnosed the + ordinary way. */ + && (TREE_CODE (fn) != TEMPLATE_ID_EXPR + || candidates->template_decl)) return cp_build_function_call_vec (candidates->fn, args, complain); // Otherwise, emit notes for non-viable candidates. @@ -6509,6 +6553,10 @@ add_candidates (tree fns, tree first_arg, const vec *args, else /*if (flags & LOOKUP_DEFAULTED)*/ which = non_templates; + /* Template candidates that we'll potentially ignore if the + perfect candidate optimization succeeds. */ + z_candidate *ignored_template_cands = nullptr; + /* During overload resolution, we first consider each function under the assumption that we'll eventually find a strictly viable candidate. This allows us to circumvent our defacto behavior when checking @@ -6519,20 +6567,29 @@ add_candidates (tree fns, tree first_arg, const vec *args, This trick is important for pruning member function overloads according to their const/ref-qualifiers (since all 'this' conversions are at worst bad) without breaking -fpermissive. */ - tree bad_fns = NULL_TREE; + z_candidate *bad_cands = nullptr; bool shortcut_bad_convs = true; again: for (tree fn : lkp_range (fns)) { - if (check_converting && DECL_NONCONVERTING_P (fn)) - continue; - if (check_list_ctor && !is_list_ctor (fn)) - continue; if (which == templates && TREE_CODE (fn) != TEMPLATE_DECL) - continue; + { + if (template_only) + add_ignored_candidate (candidates, fn); + continue; + } if (which == non_templates && TREE_CODE (fn) == TEMPLATE_DECL) - continue; + { + add_ignored_candidate (&ignored_template_cands, fn); + continue; + } + if ((check_converting && DECL_NONCONVERTING_P (fn)) + || (check_list_ctor && !is_list_ctor (fn))) + { + add_ignored_candidate (candidates, fn); + continue; + } tree fn_first_arg = NULL_TREE; const vec *fn_args = args; @@ -6589,22 +6646,19 @@ add_candidates (tree fns, tree first_arg, const vec *args, } if (TREE_CODE (fn) == TEMPLATE_DECL) - { - if (!add_template_candidate (candidates, - fn, - ctype, - explicit_targs, - fn_first_arg, - fn_args, - return_type, - access_path, - conversion_path, - flags, - strict, - shortcut_bad_convs, - complain)) - continue; - } + add_template_candidate (candidates, + fn, + ctype, + explicit_targs, + fn_first_arg, + fn_args, + return_type, + access_path, + conversion_path, + flags, + strict, + shortcut_bad_convs, + complain); else { add_function_candidate (candidates, @@ -6632,13 +6686,14 @@ add_candidates (tree fns, tree first_arg, const vec *args, { /* This candidate has been tentatively marked non-strictly viable, and we didn't compute all argument conversions for it (having - stopped at the first bad conversion). Add the function to BAD_FNS - to fully reconsider later if we don't find any strictly viable - candidates. */ + stopped at the first bad conversion). Move the candidate to + BAD_CANDS to fully reconsider later if we don't find any strictly + viable candidates. */ if (complain & (tf_error | tf_conv)) { - bad_fns = lookup_add (fn, bad_fns); - *candidates = (*candidates)->next; + *candidates = cand->next; + cand->next = bad_cands; + bad_cands = cand; } else /* But if we're in a SFINAE context, just mark this candidate as @@ -6652,21 +6707,44 @@ add_candidates (tree fns, tree first_arg, const vec *args, if (which == non_templates && !seen_perfect) { which = templates; + ignored_template_cands = nullptr; goto again; } else if (which == templates && !seen_strictly_viable && shortcut_bad_convs - && bad_fns) + && bad_cands) { /* None of the candidates are strictly viable, so consider again those - functions in BAD_FNS, this time without shortcutting bad conversions + functions in BAD_CANDS, this time without shortcutting bad conversions so that all their argument conversions are computed. */ which = either; - fns = bad_fns; + fns = NULL_TREE; + for (z_candidate *cand = bad_cands; cand; cand = cand->next) + { + tree fn = cand->fn; + if (tree ti = cand->template_decl) + fn = TI_TEMPLATE (ti); + fns = ovl_make (fn, fns); + } shortcut_bad_convs = false; + bad_cands = nullptr; goto again; } + + if (complain & tf_error) + { + /* Remember any omitted candidates if we need to print candidates + as part of overload resolution failure diagnostics. */ + for (z_candidate *omitted_cands : { ignored_template_cands, bad_cands }) + { + z_candidate **omitted_cands_tail = &omitted_cands; + while (*omitted_cands_tail) + omitted_cands_tail = &(*omitted_cands_tail)->next; + *omitted_cands_tail = *candidates; + *candidates = omitted_cands; + } + } } /* Returns 1 if P0145R2 says that the LHS of operator CODE is evaluated first, diff --git a/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C b/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C index de7570a6efa..50c25cd49b7 100644 --- a/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C +++ b/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C @@ -129,22 +129,22 @@ int test_6 (int first, const char *second, float third, s6 *ptr) /* Template function. */ template -int test_7 (int one, T two, float three); // { dg-line test_7_decl } +int callee_7 (int one, T two, float three); // { dg-line callee_7_decl } int test_7 (int first, const char *second, float third) { - return test_7 (first, second, third); // { dg-line test_7_usage } - // { dg-message "cannot convert 'const char\\*' to 'const char\\*\\*'" "" { target *-*-* } test_7_usage } + return callee_7 (first, second, third); // { dg-line callee_7_usage } + // { dg-message "cannot convert 'const char\\*' to 'const char\\*\\*'" "" { target *-*-* } callee_7_usage } /* { dg-begin-multiline-output "" } - return test_7 (first, second, third); - ^~~~~~ - | - const char* + return callee_7 (first, second, third); + ^~~~~~ + | + const char* { dg-end-multiline-output "" } */ - // { dg-message "initializing argument 2 of 'int test_7\\(int, T, float\\) .with T = const char\\*\\*.'" "" { target *-*-* } test_7_decl } + // { dg-message "initializing argument 2 of 'int callee_7\\(int, T, float\\) .with T = const char\\*\\*.'" "" { target *-*-* } callee_7_decl } /* { dg-begin-multiline-output "" } - int test_7 (int one, T two, float three); - ~~^~~ + int callee_7 (int one, T two, float three); + ~~^~~ { dg-end-multiline-output "" } */ } diff --git a/gcc/testsuite/g++.dg/overload/error6.C b/gcc/testsuite/g++.dg/overload/error6.C new file mode 100644 index 00000000000..86a12eaa8de --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/error6.C @@ -0,0 +1,9 @@ +// Verify we note even non-template candidates when diagnosing +// overload resolution failure for a template-id. + +template void f(T); // { dg-message "candidate" } +void f(int); // { dg-message {candidate: 'void f\(int\)' \(ignored\)} } + +int main() { + f(0, 0); // { dg-error "no match" } +} From patchwork Fri Oct 27 19:55:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 159143 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:d641:0:b0:403:3b70:6f57 with SMTP id cy1csp852386vqb; Fri, 27 Oct 2023 13:01:56 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFCnq+8MHMOMNmfjZig91IhuvxTY76u/SL1M48ET82AAgMyUCh11NCs8eHvdW81YOQacwU0 X-Received: by 2002:a67:b748:0:b0:452:88da:2e1f with SMTP id l8-20020a67b748000000b0045288da2e1fmr3526164vsh.21.1698436915557; Fri, 27 Oct 2023 13:01:55 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1698436915; cv=pass; d=google.com; s=arc-20160816; b=MPjq/+0/dxvXe1G4Oh5JTqRlaSqZ6rVBOJ2oLgO2Buwd6Sz5Kv3NDdfOVHoH/xLIpC kzWVqDbvD9+GpChwyYIFuej9vCFbwvM2p0NNVNcjEqiBKtLoFjl3DXqWdo4G3adwmwbO S5du5THmGbo5WdYtlIzRDGldBybIh/e++J8K81ZhH5AvGjTvd+szVk9T7vhbGCZQnghc sB0gb6qpWIkLBFY+RAd+s375hgEG+ue+EKb3HIMYTsCezUEqTtB93X6n2HNByZEYPUmK UvWNYGi7UIoJOgagZwH32vOjV3/h8u4vBtAMYXeeb5+8iJK9Fv1go7l6zO6YVaObd4dC NcBA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=parwmu7mjl0KWvdWrhOzVg9u1mtMk3fV8FAgZtuI+DY=; fh=1Hi9m88IqcWZGtfSxUrMGG+GBgL26N02X1SANXM6iTs=; b=tE7AHibcZKrjvUKV+wXes+lwfB6aCM9PrPdmeg3HoNiNNSaYxTNQG8+qKj5dNu2+3g f4F3GM6RRZ9SuV1SqL4gpYammozxsZQE/FG11al0H33gKgnS6z/uA96S4zOtYw/B07ej WUXrjWWvQXsy6Ez4yz5WQxcD4SzBul9jidR7koNjnOO3wtcjGIpaYSajLeRzGLYl6T2S SNS+uiFKZXktURzpKy+gVnlqlfMmaoj5q1X32xz8zyJlMvDUyLE6DX3ZH/9m2vifUbU0 KhTu58mc23NdYp3hgHg1KZFxQc9HLr8EVnzFBENbSbCQdren0NqgWAE0uUjowRAGYrTc EL9g== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=P1OA7Kdz; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id n7-20020a67ac47000000b0045277959cffsi322554vsh.614.2023.10.27.13.01.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Oct 2023 13:01:55 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=P1OA7Kdz; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D66673831E1A for ; Fri, 27 Oct 2023 20:01:45 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 826B0385351D for ; Fri, 27 Oct 2023 20:01:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 826B0385351D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 826B0385351D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698436880; cv=none; b=Q+RmIPHav5Ff2txr7Av2LANcly7cF9BKYXHAaFkvoVoj7qEooQU2eGcNr47gs7zmuxeGs/BlX4BXoefzpA8zyI3gYTifVztb0Di/8Ia99YlKQ9XfwHmL/qQio5COWCqWnwzqBfz3p7W47UfZF8bfSZQ9sZt/LgcPstHv78zd3jI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698436880; c=relaxed/simple; bh=IYjLemf7tjHa/q+QyLx+Fal9fOB4b2eBaYvTef2XaZc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Ys5/NAlAjdUf1g+PTMWRsRiA0lmObj0ubqapvIu8n9gtcdTFpRf5m8UD/Fi+6PUESvvPnXDYMfY33CzplHRB1dG8qlW7DyOwhtVdndo1GTnAdIIuJ5Any0uUanjlw3YBiffq0whBbUcbrAFunVhVy11xN96CfU7is9ig7OvVI9I= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1698436878; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=parwmu7mjl0KWvdWrhOzVg9u1mtMk3fV8FAgZtuI+DY=; b=P1OA7KdzbJjBFVKltekPxdJxHS9yY9TXw7/TqSeoplRWUQup8GIy9nVeyFXYGFDT7TFtss Bsv8Wiz/ilS5sVf4zaHymlwBl/MENA5SekeFo77weD0wq1sjGdYnbBi5JcuRYyGu7rgLw4 yZo8t6qI44ijhAETXS64xlUn+kC078Y= Received: from mail-vk1-f197.google.com (mail-vk1-f197.google.com [209.85.221.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-650-5AGsRO9IPImuA2s9jpP6uQ-1; Fri, 27 Oct 2023 16:01:16 -0400 X-MC-Unique: 5AGsRO9IPImuA2s9jpP6uQ-1 Received: by mail-vk1-f197.google.com with SMTP id 71dfb90a1353d-49a94be026dso918892e0c.1 for ; Fri, 27 Oct 2023 13:01:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698436875; x=1699041675; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=parwmu7mjl0KWvdWrhOzVg9u1mtMk3fV8FAgZtuI+DY=; b=KoQtvkjYf3DnN9JOasHSGzJ2rLNGu8GJHk4TMZkXxK+ARAO/Z4Qqu4bi13x/7hjQha N0uHpawfvA2zJeh0TkF/alVdlKrkmwN9Sp1I5hMN/XN2b9DotNvwedrLPaC7IAzr3lSz LLcpRKhH/7dY+5H7W+rDEj/FqexofdxerFWjBYFznSt5ci9sAoyxxnJo2BlLymdZH+jp qx+h4ahhLEK/KGi6ULV24K8/FHOu2iobuS6YYwfB3gfhOUCQACfI7F4lQIgh2/OPjhM/ NcOXMTTbW4hA9akw6SC5Ur8oT/Bqg0K2aX1Cl7qt9toX4uzLEyz6B1nQKdJv/rGEsOfz G33Q== X-Gm-Message-State: AOJu0Yx/GIgduejYnvJSaXNIQ+Fi0s7xVD0vunUk2K8DHrzPM56g4eHN 3SoQXQOtHzoyi6qbK0B9kdDW0w20tnqWo2ozr5D2IZPnNd7Vp31m/HSviEP8SEixnTEn17hbbDQ DUT6UfBDcZ3cCQetqBWAjNbN5f4AXAIgg0dfnHzwOIynKqKxjz93DPPBbKqVeUfiKWU7wqnSGA4 k= X-Received: by 2002:a1f:f2ce:0:b0:49d:92e0:9cd1 with SMTP id q197-20020a1ff2ce000000b0049d92e09cd1mr4022627vkh.11.1698436875480; Fri, 27 Oct 2023 13:01:15 -0700 (PDT) X-Received: by 2002:a1f:f2ce:0:b0:49d:92e0:9cd1 with SMTP id q197-20020a1ff2ce000000b0049d92e09cd1mr4022589vkh.11.1698436875068; Fri, 27 Oct 2023 13:01:15 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id l20-20020a0ce514000000b0065b17b925d0sm910777qvm.38.2023.10.27.13.01.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Oct 2023 13:01:13 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH v3 3/3] c++: note other candidates when diagnosing deletedness Date: Fri, 27 Oct 2023 15:55:31 -0400 Message-ID: <20231027195532.2566822-3-ppalka@redhat.com> X-Mailer: git-send-email 2.42.0.482.g2e8e77cbac In-Reply-To: <20231027195532.2566822-1-ppalka@redhat.com> References: <20231027195532.2566822-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780940186888537568 X-GMAIL-MSGID: 1780940186888537568 With the previous two patches in place, we can now extend our deletedness diagnostic to note the other considered candidates, e.g.: deleted16.C: In function 'int main()': deleted16.C:10:4: error: use of deleted function 'void f(int)' 10 | f(0); | ~^~~ deleted16.C:5:6: note: declared here 5 | void f(int) = delete; | ^ deleted16.C:5:6: note: candidate: 'void f(int)' (deleted) deleted16.C:6:6: note: candidate: 'void f(...)' 6 | void f(...); | ^ deleted16.C:7:6: note: candidate: 'void f(int, int)' 7 | void f(int, int); | ^ deleted16.C:7:6: note: candidate expects 2 arguments, 1 provided These notes are controlled by a new command line flag -fnote-all-cands, which also controls whether we note ignored candidates more generally. gcc/ChangeLog: * doc/invoke.texi (C++ Dialect Options): Document -fnote-all-cands. gcc/c-family/ChangeLog: * c.opt: Add -fnote-all-cands. gcc/cp/ChangeLog: * call.cc (print_z_candidates): Only print ignored candidates when -fnote-all-cands is set. (build_over_call): When diagnosing deletedness, call print_z_candidates if -fnote-all-cands is set. gcc/testsuite/ChangeLog: * g++.dg/overload/error6.C: Pass -fnote-all-cands. * g++.dg/cpp0x/deleted16.C: New test. --- gcc/c-family/c.opt | 4 ++++ gcc/cp/call.cc | 8 +++++++- gcc/doc/invoke.texi | 5 +++++ gcc/testsuite/g++.dg/cpp0x/deleted16.C | 25 +++++++++++++++++++++++++ gcc/testsuite/g++.dg/overload/error6.C | 1 + 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/deleted16.C diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 44b9c862c14..a76f73cc661 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -2006,6 +2006,10 @@ fnil-receivers ObjC ObjC++ Var(flag_nil_receivers) Init(1) Assume that receivers of Objective-C messages may be nil. +fnote-all-cands +C++ ObjC++ Var(flag_note_all_cands) +Note all candidates during overload resolution failure. + flocal-ivars ObjC ObjC++ Var(flag_local_ivars) Init(1) Allow access to instance variables as if they were local declarations within instance method implementations. diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 81cc029dddb..7ace0e65096 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -4090,6 +4090,8 @@ print_z_candidates (location_t loc, struct z_candidate *candidates, { if (only_viable_p.is_true () && candidates->viable != 1) break; + if (ignored_candidate_p (candidates) && !flag_note_all_cands) + break; print_z_candidate (loc, N_("candidate:"), candidates); } } @@ -9933,7 +9935,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (DECL_DELETED_FN (fn)) { if (complain & tf_error) - mark_used (fn); + { + mark_used (fn); + if (cand->next && flag_note_all_cands) + print_z_candidates (input_location, cand, /*only_viable_p=*/false); + } return error_mark_node; } diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 5a9284d635c..ac82299416c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3479,6 +3479,11 @@ Disable built-in declarations of functions that are not mandated by ANSI/ISO C@. These include @code{ffs}, @code{alloca}, @code{_exit}, @code{index}, @code{bzero}, @code{conjf}, and other related functions. +@opindex fnote-all-cands +@item -fnote-all-cands +Permit the C++ front end to note all candidates during overload resolution +failure, including when a deleted function is selected. + @opindex fnothrow-opt @item -fnothrow-opt Treat a @code{throw()} exception specification as if it were a diff --git a/gcc/testsuite/g++.dg/cpp0x/deleted16.C b/gcc/testsuite/g++.dg/cpp0x/deleted16.C new file mode 100644 index 00000000000..506caae76b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/deleted16.C @@ -0,0 +1,25 @@ +// Verify -fnote-all-cands causes us to note other candidates when a deleted +// function is selected by overload resolution. +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fnote-all-cands" } + +void f(int) = delete; // { dg-message "declared here|candidate" } +void f(...); // { dg-message "candidate" } +void f(int, int); // { dg-message "candidate" } + +// An example where the perfect candidate optimization causes us +// to ignore function templates. +void g(int) = delete; // { dg-message "declared here|candidate" } +template void g(T); // { dg-message "candidate" } + +// An example where we have a strictly viable candidate and +// an incompletely considered bad candidate. +template void h(T, T) = delete; // { dg-message "declared here|candidate" } +void h(int*, int) = delete; // { dg-message "candidate" } + +int main() { + f(0); // { dg-error "deleted" } + g(0); // { dg-error "deleted" } + h(1, 1); // { dg-error "deleted" } + // { dg-error "invalid conversion" "" { target *-*-* } .-1 } when noting 2nd cand +} diff --git a/gcc/testsuite/g++.dg/overload/error6.C b/gcc/testsuite/g++.dg/overload/error6.C index 86a12eaa8de..ac513824887 100644 --- a/gcc/testsuite/g++.dg/overload/error6.C +++ b/gcc/testsuite/g++.dg/overload/error6.C @@ -1,5 +1,6 @@ // Verify we note even non-template candidates when diagnosing // overload resolution failure for a template-id. +// { dg-additional-options "-fnote-all-cands" } template void f(T); // { dg-message "candidate" } void f(int); // { dg-message {candidate: 'void f\(int\)' \(ignored\)} }