From patchwork Tue Oct 10 03:22:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1845577 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=KIb4qj6N; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4S4Lp06mQlz1ypX for ; Tue, 10 Oct 2023 14:23:20 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0AF8A3858404 for ; Tue, 10 Oct 2023 03:23:18 +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 B1F203858D28 for ; Tue, 10 Oct 2023 03:23:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B1F203858D28 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1696908185; 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=YgKZQiIYl2hB81IeRHCBwJj/HuDTBtLb6Ycp2RTfDJA=; b=KIb4qj6N1E1+mtALuFDGOAWNddfYwDEhMVWs7ZXBEfeflXfEa+FgdNIncBcjFaBEghYU6J DhUY/XGdo5dHuKou5bC8PBlN8ZrngniwbRfrw60t4kFOD43M1sYEBdxxOSkDlHxJfo3ct0 wLHqi8+zx7hWzaFGzLJzfba4IQwPCtU= Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-655-NjEEQ2UwP3GQnXBzluj8Mg-1; Mon, 09 Oct 2023 23:23:04 -0400 X-MC-Unique: NjEEQ2UwP3GQnXBzluj8Mg-1 Received: by mail-qv1-f70.google.com with SMTP id 6a1803df08f44-65b0249818dso65556306d6.1 for ; Mon, 09 Oct 2023 20:23:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696908183; x=1697512983; 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=YgKZQiIYl2hB81IeRHCBwJj/HuDTBtLb6Ycp2RTfDJA=; b=jovs3Wf76AI6LCQB0ENSQRkJAAepxGmrZcS9yJSnnmHpBqW55Yc4ltChrLqjfWJG1G EWRLFPABGc2BeFNbblurFAGPLU0bAEkJxFRF1nAdRI/l+9eIn7Xrf9KpFJtAHQTcWdVK HK6J+kSMyn6MFBiWcs67b95DGuiS/MzxoQuZQ9ZIei77ILv29pxgtoVrWWWhVmov57kG rmB/w2tYuQRE5OxTetYh9euNPXm0u4Z3qtYqsqRdGlba12b3QNDjIdOy4npWkTWYy0y0 D+bsW8ONgtQzsL3Euvsu7Dhwz07djI+MnkZv6w+YwJQqgtA/OynQ6oMCzB+IvAAh/jTC 0rbg== X-Gm-Message-State: AOJu0YwMBVcc+Kp1iYyrbThs6V7RgL9gi6sNBPKT70KQeUPkqr3ZKdir Cyt1yf9Lvc8MQ08m+4DBh6jJDl0ZyOO51WMWo/WjjKRIJaZis0B2OlCe6pdAQxXCorugg6jA8Si ju8dIUfVtkE4E6+jHoKTzmnVRid8gFL8wxfNKTSk1FeTZPwaIv6G468lTzAkeMK2NVUexQAwdMc E= X-Received: by 2002:a05:6214:2f03:b0:658:22d8:9 with SMTP id od3-20020a0562142f0300b0065822d80009mr18168137qvb.61.1696908183127; Mon, 09 Oct 2023 20:23:03 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEewKp5VMW1z/Pg6o9eksGHLm+jhu8fMfzu8vm4UbyDSKPaGZk5RL2bPoCXIiomX0s7kB5pSA== X-Received: by 2002:a05:6214:2f03:b0:658:22d8:9 with SMTP id od3-20020a0562142f0300b0065822d80009mr18168125qvb.61.1696908182682; Mon, 09 Oct 2023 20:23:02 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id c10-20020a0cf2ca000000b0065afd35c762sm4346144qvm.91.2023.10.09.20.23.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Oct 2023 20:23:02 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH 1/2] c++: sort candidates according to viability Date: Mon, 9 Oct 2023 23:22:59 -0400 Message-ID: <20231010032300.1057862-1-ppalka@redhat.com> X-Mailer: git-send-email 2.42.0.325.g3a06386e31 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+incoming=patchwork.ozlabs.org@gcc.gnu.org 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. gcc/testsuite/ChangeLog: * g++.dg/overload/error5.C: New test. --- gcc/cp/call.cc | 161 +++++++++++++++---------- gcc/testsuite/g++.dg/overload/error5.C | 11 ++ 2 files changed, 111 insertions(+), 61 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/error5.C diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 15079ddf6dc..648d383ca4e 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 *); @@ -3718,68 +3720,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 unviable 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 *unviable = nullptr; + z_candidate **unviable_tail = &unviable; /* 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 + : unviable_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. */ + *unviable_tail = nullptr; + *non_strictly_viable_tail = unviable; + *strictly_viable_tail = non_strictly_viable; + + return strictly_viable; } static bool @@ -4013,8 +4007,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; @@ -4059,8 +4058,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 unviable 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 @@ -13186,38 +13196,50 @@ 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; int fate; struct z_candidate *champ_compared_to_predecessor = nullptr; + struct z_candidate *champ_predecessor = nullptr; + struct z_candidate *challenger_predecessor = champ; /* 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 = champ->next; challenger && challenger->viable; ) { fate = joust (champ, challenger, 0, complain); if (fate == 1) - challenger = challenger->next; + { + challenger_predecessor = challenger; + challenger = challenger->next; + } else { if (fate == 0) { + champ_predecessor = challenger; champ = challenger->next; - if (champ == 0) - return NULL; + if (!champ || !champ->viable) + { + champ = nullptr; + break; + } champ_compared_to_predecessor = nullptr; } else { champ_compared_to_predecessor = champ; + champ_predecessor = challenger_predecessor; champ = challenger; } + challenger_predecessor = champ; challenger = champ->next; } } @@ -13225,14 +13247,31 @@ tourney (struct z_candidate *candidates, tsubst_flags_t complain) /* Make sure the champ is better than all the candidates it hasn't yet been compared to. */ - for (challenger = candidates; - challenger != champ - && challenger != champ_compared_to_predecessor; - challenger = challenger->next) + if (champ) + for (challenger = candidates; + challenger != champ + && challenger != champ_compared_to_predecessor; + challenger = challenger->next) + { + 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) { - fate = joust (champ, challenger, 0, complain); - if (fate != 1) - return NULL; + gcc_checking_assert (champ_predecessor->next == champ); + champ_predecessor->next = champ->next ? champ->next->next : nullptr; + champ->next = candidates; + candidates = champ; } return champ; diff --git a/gcc/testsuite/g++.dg/overload/error5.C b/gcc/testsuite/g++.dg/overload/error5.C new file mode 100644 index 00000000000..a5e4bb4bf33 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/error5.C @@ -0,0 +1,11 @@ +// Verify we explain why all three candidates failed to match. +// The presence of the first two non-strictly viable candidates +// used to make us not explain the third unviable candidate. + +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 Tue Oct 10 03:23:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1845578 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=HiX6yR4U; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4S4LpZ6fHVz1ypX for ; Tue, 10 Oct 2023 14:23:50 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 010EF3857029 for ; Tue, 10 Oct 2023 03:23:49 +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 0EA6B385840F for ; Tue, 10 Oct 2023 03:23:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0EA6B385840F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1696908191; 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=LvDWfMUX1SQ6gzARClvcTr+hhD3gbrtXoi4k7XHjby0=; b=HiX6yR4Ufd3pomqKHZ9uHHzlnCXg/iAQoT5F42FT8L/H0B4Tq4iQpMVzSDTT55QaRwn/f8 MHdFwwEh0YuCLkvn2kBdK5Cxo2kZSkdNF/4AZL66qmWzqxrlaMva6gPPNl8ZFThZSNlUpF sOLnlUMTOZYSPS8fHy8UtsPynnv36GU= Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-641-J5d4PNWbOHCkQogKttRhfg-1; Mon, 09 Oct 2023 23:23:05 -0400 X-MC-Unique: J5d4PNWbOHCkQogKttRhfg-1 Received: by mail-qv1-f69.google.com with SMTP id 6a1803df08f44-66cf8d4b5e4so6856d6.3 for ; Mon, 09 Oct 2023 20:23:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696908184; x=1697512984; 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=LvDWfMUX1SQ6gzARClvcTr+hhD3gbrtXoi4k7XHjby0=; b=KtVljYy7F6DepXPbYk4G93/tarzOcM5bsUJowhMS+E6dVE+7Bt5ZkKjrHJA+0zSM9v 3kZ6GL9yLolhOix2cRmzMrycVwoKSCljy4ywOkVXuQBCxgik45ZFzMdndZGLxxLTQVjd 2xK2kjsyUolPDAolswr0m7BqCCZfN46U71BxvGCbtQg0EEVB/xPao7GItCAXypkUmLAs eTcbHC//yeBjJilKoEdOFpw0gyFz1EaX9gF5kMKkC6dXDmEumZMnSs5TrVUScBhfkrFN 9oqDqiF/iuvKlKBXiP4vFRn9GkDOy16iTVNKIcf0VYOPuZJ5okBtdA5aet3lL6vLsbw6 VHtA== X-Gm-Message-State: AOJu0YzPYuoBAY7hG8tKx7neym/Lx5dxI+ys8fW1Svz+0K6Gh5C7JgpJ 9tMV0eLKYc0bGvL0NihDqk2Rw2RJzj8T8pvwG2FotyxuYNh9bC+OtQzeH8KP9byPcYENACNlQ0Z Y5SnVETnO/98PbGqIMhpxO8a36Lgh4cGcBdoRg7eAV71nT1ExejaG0S+IoMz9wS8jNg2X/jem7K s= X-Received: by 2002:ad4:5949:0:b0:64f:51fe:859c with SMTP id eo9-20020ad45949000000b0064f51fe859cmr21226393qvb.43.1696908184506; Mon, 09 Oct 2023 20:23:04 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH5+2p2CzKEW8nWOjGmWcowVEjjbny1caOsODjjt7q09wcMpZUlI/CvEUNv7ULLvMYaRFYI1Q== X-Received: by 2002:ad4:5949:0:b0:64f:51fe:859c with SMTP id eo9-20020ad45949000000b0064f51fe859cmr21226382qvb.43.1696908184192; Mon, 09 Oct 2023 20:23:04 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id c10-20020a0cf2ca000000b0065afd35c762sm4346144qvm.91.2023.10.09.20.23.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Oct 2023 20:23:03 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH 2/2] c++: note other candidates when diagnosing deletedness Date: Mon, 9 Oct 2023 23:23:00 -0400 Message-ID: <20231010032300.1057862-2-ppalka@redhat.com> X-Mailer: git-send-email 2.42.0.325.g3a06386e31 In-Reply-To: <20231010032300.1057862-1-ppalka@redhat.com> References: <20231010032300.1057862-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+incoming=patchwork.ozlabs.org@gcc.gnu.org With the previous improvements in place, we can easily extend our deletedness diagnostic to note the other candidates: 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 disabled when a deleted special member function is selected primarily because it introduces a lot of new "cannot bind reference" errors in the testsuite when noting non-viable candidates, e.g. in cpp0x/initlist-opt1.C we would need to expect an error at A(A&&). gcc/cp/ChangeLog: * call.cc (build_over_call): Call print_z_candidates when diagnosing deletedness. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/deleted16.C: New test. --- gcc/cp/call.cc | 10 +++++++++- gcc/testsuite/g++.dg/cpp0x/deleted16.C | 11 +++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/deleted16.C diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 648d383ca4e..55fd71636b1 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -9873,7 +9873,15 @@ 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); + /* Note the other candidates we considered unless we selected a + special member function since the mismatch reasons for other + candidates are usually uninteresting, e.g. rvalue vs lvalue + reference binding . */ + if (cand->next && !special_memfn_p (fn)) + print_z_candidates (input_location, cand, /*only_viable_p=*/false); + } return error_mark_node; } diff --git a/gcc/testsuite/g++.dg/cpp0x/deleted16.C b/gcc/testsuite/g++.dg/cpp0x/deleted16.C new file mode 100644 index 00000000000..9fd2fbb1465 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/deleted16.C @@ -0,0 +1,11 @@ +// Verify we note other candidates when a deleted function is +// selected by overload resolution. +// { dg-do compile { target c++11 } } + +void f(int) = delete; // { dg-message "declared here|candidate" } +void f(...); // { dg-message "candidate" } +void f(int, int); // { dg-message "candidate" } + +int main() { + f(0); // { dg-error "deleted" } +}