From patchwork Wed Dec 14 17:48:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1715872 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=PU8dd+Ec; dkim-atps=neutral Received: from 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 (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NXNCC0pRpz23yy for ; Thu, 15 Dec 2022 04:48:52 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A4DBD3832354 for ; Wed, 14 Dec 2022 17:48:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A4DBD3832354 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1671040130; bh=H393ajTKssWPocThS4Sa8Hh+lwpMpjXCZZlsrSx7y34=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=PU8dd+Ec4HNUxc2HcS/hWF/vW7Tiz2xwQUedEBZ8qmQlBnFhDVp8CUztFOA4GFIIF eUTWJ7MU9/tOo+J8xiy17patO/G21J7yLcjWOgR32TDq0XsuCDqLysjNuXiCdqHUTY D7/gltSTOQ+YH2MM7iciC+C6WMk4FSe42Adx8Otc= 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 86738383236A for ; Wed, 14 Dec 2022 17:48:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 86738383236A Received: from mail-vs1-f69.google.com (mail-vs1-f69.google.com [209.85.217.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-648-XL8AoddbODO30u1JJJn9qQ-1; Wed, 14 Dec 2022 12:48:30 -0500 X-MC-Unique: XL8AoddbODO30u1JJJn9qQ-1 Received: by mail-vs1-f69.google.com with SMTP id k30-20020a67ef5e000000b003b139171497so142960vsr.9 for ; Wed, 14 Dec 2022 09:48:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=H393ajTKssWPocThS4Sa8Hh+lwpMpjXCZZlsrSx7y34=; b=sSkFNSAVCp1fHfOqNLQdEcm3TjTm+j6TO1p5VmluD3Bkk+hTuDH0QEVsczjrsumuWJ Xa+Xph7LGDpLFVgPu+BDFYvDsgMbNptRBNqo/SwObdNQGysf62cEt+JyvZa0LYcQ4Mnh AbeUP69oyjuyvLUbcuCIyD2nvu/mfNlEJrY1rq0N96uEeotxwDQ5xhbIsgVzr4nrgnlR LiJb+5X8+2HzWP6CCIlemmzJbgsh9Zkfd3ie0G18Eci2OJOPuqhm9LLCjV6sbfAcWWkh z6OboVboSqn1jWjx59U4fZrNdzayBZ6oOXuVEoMOPFT6Of7sVvAgq1RSXkG21acxSEnE j8QA== X-Gm-Message-State: ANoB5pmdnlyqPmnFOVPJUU9gH0Ag9S2GVkm5hxRFbr5lUMcXFs/XD5fc QvwCppONLnnrQt+bgTT0RQ3z8Yi/ZKLgHzQ2eYEh9pUTaP91UtVOuIx0mw8NEQg2Ng5fHp/OKZq SUVePWAJZVUX2Ir4m13r64W+KKaXTrMChHW8UIp2W4xHzHZ3ML5RJmNoCfZgk4P4GzUY= X-Received: by 2002:a67:efdb:0:b0:3b0:796c:7a37 with SMTP id s27-20020a67efdb000000b003b0796c7a37mr16827953vsp.28.1671040108473; Wed, 14 Dec 2022 09:48:28 -0800 (PST) X-Google-Smtp-Source: AA0mqf568yCTH5coUa6DCi+YDkDyxrcOdEpZNqTPYOLU9V0wVsuIoSIxRrIoT5btnS+isVwEm8g87Q== X-Received: by 2002:a67:efdb:0:b0:3b0:796c:7a37 with SMTP id s27-20020a67efdb000000b003b0796c7a37mr16827917vsp.28.1671040108033; Wed, 14 Dec 2022 09:48:28 -0800 (PST) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id dm20-20020a05620a1d5400b006fca1691425sm10190878qkb.63.2022.12.14.09.48.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Dec 2022 09:48:27 -0800 (PST) To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] c++: local alias in typename in lambda [PR105518] Date: Wed, 14 Dec 2022 12:48:25 -0500 Message-Id: <20221214174825.2340493-1-ppalka@redhat.com> X-Mailer: git-send-email 2.39.0.56.g57e2c6ebbe MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.7 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_H2, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" We substitute the qualifying scope of a TYPENAME_TYPE directly using tsubst_aggr_type (so that we can pass entering_scope=true) instead of going through tsubst, which means we don't properly reuse typedefs during this substitution. This ends up causing us to reject the below testcase because we substitute the TYPENAME_TYPE impl::type as if it were written without the typedef impl for A, and thus we expect the non-capturing lambda to capture t. This patch fixes this by making tsubst_aggr_type delegate typedefs to tsubst so that get properly reused, and then adjusting the result appropriately if entering_scope is true. In passing, this refactors tsubst_aggr_type into two functions, one that's intended to be called directly and a more minimal one that's intended to be called only from the RECORD/UNION/ENUMERAL_TYPE cases of tsubst (and contains only the necessary bits for that call site). Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? Patch generated with -w to suppress noisy whitespace changes. PR c++/105518 gcc/cp/ChangeLog: * pt.cc (tsubst_aggr_type): Handle typedefs by delegating to tsubst and adjusting the result if entering_scope. Split out the main part of the function into ... (tsubst_aggr_type_1) ... here. (tsubst): Use tsubst_aggr_type_1 instead of tsubst_aggr_type. Handle TYPE_PTRMEMFUNC_P RECORD_TYPEs here instead of in tsubst_aggr_type_1. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/lambda/lambda-alias1.C: New test. --- gcc/cp/pt.cc | 58 ++++++++++++++----- .../g++.dg/cpp0x/lambda/lambda-alias1.C | 23 ++++++++ 2 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-alias1.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 81b7787fd3d..86862e56410 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -185,6 +185,7 @@ static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static void tsubst_each_template_parm_constraints (tree, tree, tsubst_flags_t); tree most_specialized_partial_spec (tree, tsubst_flags_t); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); +static tree tsubst_aggr_type_1 (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); static bool check_specialization_scope (void); @@ -13845,23 +13846,49 @@ tsubst_aggr_type (tree t, if (t == NULL_TREE) return NULL_TREE; - /* If T is an alias template specialization, we want to substitute that - rather than strip it, especially if it's dependent_alias_template_spec_p. - It should be OK not to handle entering_scope in this case, since - DECL_CONTEXT will never be an alias template specialization. We only get - here with an alias when tsubst calls us for TYPENAME_TYPE. */ - if (alias_template_specialization_p (t, nt_transparent)) - return tsubst (t, args, complain, in_decl); + /* Handle typedefs via tsubst so that they get reused. */ + if (typedef_variant_p (t)) + { + t = tsubst (t, args, complain, in_decl); + if (t == error_mark_node) + return error_mark_node; + + /* The effect of entering_scope is that when substitution yields a + dependent specialization A, lookup_template_class prefers to + return A's primary template type instead of the implicit instantiation. + So when entering_scope, we mirror this behavior by inspecting + TYPE_CANONICAL appropriately, taking advantage of the fact that + lookup_template_class links the two types by setting TYPE_CANONICAL of + the latter to the former. */ + if (entering_scope + && CLASS_TYPE_P (t) + && dependent_type_p (t) + && TYPE_CANONICAL (t) == TREE_TYPE (TYPE_TI_TEMPLATE (t))) + t = TYPE_CANONICAL (t); + return t; + } switch (TREE_CODE (t)) { case RECORD_TYPE: - if (TYPE_PTRMEMFUNC_P (t)) - return tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl); - - /* Fall through. */ case ENUMERAL_TYPE: case UNION_TYPE: + return tsubst_aggr_type_1 (t, args, complain, in_decl, entering_scope); + + default: + return tsubst (t, args, complain, in_decl); + } +} + +/* The part of tsubst_aggr_type that's shared with tsubst. */ + +static tree +tsubst_aggr_type_1 (tree t, + tree args, + tsubst_flags_t complain, + tree in_decl, + int entering_scope) +{ if (TYPE_TEMPLATE_INFO (t) && uses_template_parms (t)) { tree argvec; @@ -13892,10 +13919,6 @@ tsubst_aggr_type (tree t, else /* This is not a template type, so there's nothing to do. */ return t; - - default: - return tsubst (t, args, complain, in_decl); - } } /* Map from a FUNCTION_DECL to a vec of default argument instantiations, @@ -15812,9 +15835,12 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) switch (code) { case RECORD_TYPE: + if (TYPE_PTRMEMFUNC_P (t)) + return tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl); + /* Fall through. */ case UNION_TYPE: case ENUMERAL_TYPE: - return tsubst_aggr_type (t, args, complain, in_decl, + return tsubst_aggr_type_1 (t, args, complain, in_decl, /*entering_scope=*/0); case ERROR_MARK: diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-alias1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-alias1.C new file mode 100644 index 00000000000..4ac69935054 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-alias1.C @@ -0,0 +1,23 @@ +// PR c++/105518 +// { dg-do compile { target c++11 } } + +struct integral_constant { + constexpr operator int() const { return 42; } +}; + +template +struct A { + using type = A; + static constexpr int value = N; +}; + +template +void f(T t) { + using impl = A; + [] (int) { + typename impl::type a; // { dg-bogus "'t' is not captured" } + return a.value; + }(0); +} + +template void f(integral_constant);