From patchwork Tue Aug 6 06:35:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 95351 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BDB87385840F for ; Tue, 6 Aug 2024 06:35:57 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-oi1-x22f.google.com (mail-oi1-x22f.google.com [IPv6:2607:f8b0:4864:20::22f]) by sourceware.org (Postfix) with ESMTPS id E6FE83858401 for ; Tue, 6 Aug 2024 06:35:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E6FE83858401 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E6FE83858401 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::22f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722926131; cv=none; b=JDUMknTWRPug75mzPqGTzUDzJo9FWvHuEK7ZKd2vr29/1cMdxRBzouJyI+fc+LL9dv8MxACwpc5rA49h+JTVt2PUMcSL+jhXQVxvL6suoODPcAS3cNVnUbZz8msKX1IO5WHWviSHYObasp45OG5ba9IjtYuQtPquHeplIHCYetw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722926131; c=relaxed/simple; bh=iYHyUDBBnL0FYpTfw9OGDgte6nJgEkRy9d3oZKJeO8o=; h=DKIM-Signature:Message-ID:Date:From:To:Subject:MIME-Version; b=W2sYNrCq09QscZGbIdV+TyT4gin349AilVsjlevel/Z8EErUt0pPRYKd181tP4iWPPxV2zKddQpOn2crUErNHhsTQ7cZ2nhnclzHPt1bJcUjKAHjDzgCayTgZTeNjrUwvMrsL4n7k0GOam9mkHubMG8WtVfaKvHm8wwEHUsJZN4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-oi1-x22f.google.com with SMTP id 5614622812f47-3db145c8010so115162b6e.3 for ; Mon, 05 Aug 2024 23:35:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1722926128; x=1723530928; darn=gcc.gnu.org; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=CsSfjMnXGoURWAaE9pTNAqwjLSNnXm+hbZ0wAlKybfE=; b=kYclx9gBWDTRLWq0dWcVXfkRTTgXNx3UYq9ddOcDHb2F9RQdUssMT4F/Xd5e0x0lm1 x4BJtFAfFPdJomEQYBqKwQjdfkgpQFn6YOGM2wEqKSaEkQKooiUNQUvt00pCpB7UR/iF gJaJWNDqFufi3DgWJ1QoGXuS0aJLP8dilh3pc0ZA4W6KgDbgyYtmZFXcrO3kDQdBwBzb o8iRwvvcInDfvcfGAEtAmZPDSZPQeXyOtpG+LBT8AfrQnyEuzKutYyVrQ+Vn/k4MUigf NQfoamjFJLN4+68bDLm31pFBBQUH17qZMu0ShIom4SaDE4r+ho8v9i8swTIPK5+tS+oc OaPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722926128; x=1723530928; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=CsSfjMnXGoURWAaE9pTNAqwjLSNnXm+hbZ0wAlKybfE=; b=C911Rh7KM7jPprdltur5zSV4KdA+iMs+JuiDsHTpyp5ha3k5C22JZcW1EwbmnChaYV pN/3pONZgpPihQ4GV1xokCgkR+xDSPG8GDswVHGGmroJBuirEhDpcAA3crPkdTclCHbR oCG5vuTnAeP0ts1q9lTQfJSj1auSTpJL2b7K1429MI6NhlLHCIiBAqmyH9uAYOasdLzd F6XTBXwJYy8k7nadBY9w5S8AwcSsphOvg2/2s8ZqY4l96L0OIh1mxGNrM8lCBSMEqTA3 KIEw1igdlRbB1fJ0S+xJ1vxd9QEUItHpV9YzeaniLPBWtSua22b1lYAw7mlkzsNXHCda i+Ig== X-Gm-Message-State: AOJu0YyQY/zpVxNVcIMCDwcS5IV9zDgdN9pGFst5eUkFEJXNiimm0sPj VRTFa9P+MkiYH5JkRMFYzIpNWeaXCrG/uBOyO1IE6yR7X78lXkY7pac3dg== X-Google-Smtp-Source: AGHT+IF+003YTgJpZ8vXNYtA3g5k6A5fYXdnvCN16N92TLiCaUwvzAW1dw26mKFlUbes0edE2DqxaA== X-Received: by 2002:a05:6808:301e:b0:3da:a032:24c5 with SMTP id 5614622812f47-3db5580dd35mr14980723b6e.22.1722926127923; Mon, 05 Aug 2024 23:35:27 -0700 (PDT) Received: from Thaum. (110-174-164-242.static.tpgi.com.au. [110.174.164.242]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7b762e9c2dasm5380221a12.8.2024.08.05.23.35.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Aug 2024 23:35:27 -0700 (PDT) Message-ID: <66b1c42f.650a0220.209cec.04ea@mx.google.com> X-Google-Original-Message-ID: Date: Tue, 6 Aug 2024 16:35:21 +1000 From: Nathaniel Shead To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Nathan Sidwell Subject: [PATCH] c++/modules: Handle instantiating qualified template friend classes [PR115801] MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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~patchwork=sourceware.org@gcc.gnu.org Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? Another potential approach would be to go searching for this unexported type and load it, either with a new LOOK_want::ANY_REACHABLE flag or by expanding on the lookup_imported_temploid_friend hack. I'm still not exactly sure how name lookup for template friends is supposed to behave though, specifically in terms of when and where they should conflict with other entities with the same name. The relevant paragraphs seem to be https://eel.is/c++draft/temp.friend#2 and/or https://eel.is/c++draft/dcl.meaning.general#2.2.2, in addition to the usual rules in [basic.link] and [basic.scope.scope], but how these all are supposed to interact isn't super clear to me right now. Additionally I wonder if maybe the better approach long-term would be to focus on getting textual redefinitions working first, and then reuse whatever logic we build for that to handle template friends rather than relying on finding these hidden 'mergeable' slots first. -- >8 -- With modules it may be the case that a template friend class provided with a qualified name is not found by name lookup at instantiation time, due to the class not being exported from its module. This causes issues in tsubst_friend_class which did not handle this case. This patch fixes the issue by just doing nothing when it detects this case; this causes the named class to be added as a pending friend which will be resolved once a definition is seen (lazy loaded). PR c++/115801 gcc/cp/ChangeLog: * pt.cc (tsubst_friend_class): Handle friend_tmpl without extra template parms. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-friend-16_a.C: New test. * g++.dg/modules/tpl-friend-16_b.C: New test. Signed-off-by: Nathaniel Shead Signed-off-by: Nathaniel Shead --- gcc/cp/pt.cc | 9 +++++ .../g++.dg/modules/tpl-friend-16_a.C | 40 +++++++++++++++++++ .../g++.dg/modules/tpl-friend-16_b.C | 17 ++++++++ 3 files changed, 66 insertions(+) create mode 100644 gcc/testsuite/g++.dg/modules/tpl-friend-16_a.C create mode 100644 gcc/testsuite/g++.dg/modules/tpl-friend-16_b.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 77fa5907c3d..f7c57d16666 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -11800,6 +11800,15 @@ tsubst_friend_class (tree friend_tmpl, tree args) input_location = saved_input_location; } } + else if (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (friend_tmpl)) + <= TMPL_ARGS_DEPTH (args)) + /* The friend template has not been declared, but is something like + + template friend class ::C; + + for an existing declaration that was not found by name lookup (not + exported from its module interface). There's nothing to do here. */ + tmpl = friend_tmpl; else { /* The friend template has not already been declared. In this diff --git a/gcc/testsuite/g++.dg/modules/tpl-friend-16_a.C b/gcc/testsuite/g++.dg/modules/tpl-friend-16_a.C new file mode 100644 index 00000000000..e1cdcd98e1e --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-friend-16_a.C @@ -0,0 +1,40 @@ +// PR c++/115801 +// { dg-additional-options "-fmodules-ts -Wno-global-module" } +// { dg-module-cmi test } + +module; + +template struct GMF; +template struct GMF_Hidden { + int go() { GMF gmf; return gmf.x; } +}; + +template struct GMF { +private: + template friend struct ::GMF_Hidden; + int x = 1; +}; + +template int test_gmf() { + GMF_Hidden h; return h.go(); +} + +export module test; + +export using ::GMF; +export using ::test_gmf; + +export template struct Attached; +template struct Attached_Hidden { + int go() { Attached attached; return attached.x; } +}; + +template struct Attached { +private: + template friend struct ::Attached_Hidden; + int x = 2; +}; + +export template int test_attached() { + Attached_Hidden h; return h.go(); +} diff --git a/gcc/testsuite/g++.dg/modules/tpl-friend-16_b.C b/gcc/testsuite/g++.dg/modules/tpl-friend-16_b.C new file mode 100644 index 00000000000..d3484ab19b1 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-friend-16_b.C @@ -0,0 +1,17 @@ +// PR c++/115801 +// { dg-additional-options "-fmodules-ts" } + +import test; + +int main() { + GMF gmf; + Attached attached; + + int a = test_gmf(); + int b = test_attached(); + + GMF_Hidden gmf_hidden; // { dg-error "not declared" } + Attached_Hidden attached_hidden; // { dg-error "not declared" } +} + +// { dg-prune-output "expected primary-expression" }