From patchwork Tue Feb 27 20:48:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1905438 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=LY5n5J1B; 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 4TkqND3S4lz23d3 for ; Wed, 28 Feb 2024 07:49:16 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 53D083858401 for ; Tue, 27 Feb 2024 20:49:14 +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 D7BC93858C98 for ; Tue, 27 Feb 2024 20:48:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D7BC93858C98 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 D7BC93858C98 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=1709066937; cv=none; b=FAE3qxpV/X370ugACp8ZoX3fW8adoltbob7DnVxrOXCvMb7HUtIBc9Pc5p6qOzkjUEzJ/pv8ugSDyeKsRTZRuRaPoGs7ZEzDxXoOTgI3sr8oiMz48kG6TPZ8Lp82Lat7uZqYTSD4+3YF8AnfR2L32nQLm91Z8W1W173LdVApC/8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709066937; c=relaxed/simple; bh=CmdP1o6kFth0vMuWTxGXvT++crNU0hExOjdbY579N94=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=gfV3anu+cLbo+NtSiUHtjrJxR7YDvj/C4GVW44YYPEJFRsMi2tS4h0nLexuXl/jZy24UwpxFOkTlRMOxqSSB04irgf4YZsRJ47hyQaJCN9CiXdcWPHENgu5Q2SxcuqvX9O+Vwgcm0qpBLMKROQqHjmqZkaLDYrg2HiZ8ACRCw7E= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709066926; 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=F5gtz7+SJhkC2ifuZ7ba6h0uIgL76NRETsukAtjYrdo=; b=LY5n5J1Ba/r3jT84c9MmvdnYAehM7FCPFUPJ5faGwwCPYmTkgd/ttXYngQy4etYikM+0so /+Qb9ehinpvsQEdykjEoM/t+9ZcPe/Mk41q3Y6KuZpkN0n7K3oPkE4FLIhX1ArwOHiGulg gk7kWMKmDxQUtfJAEZp2mrlb0wZvbCY= Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-86-BTKtrlb6PNK4IbCepBz8og-1; Tue, 27 Feb 2024 15:48:45 -0500 X-MC-Unique: BTKtrlb6PNK4IbCepBz8og-1 Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-787bd91c5feso349492785a.0 for ; Tue, 27 Feb 2024 12:48:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709066923; x=1709671723; 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=F5gtz7+SJhkC2ifuZ7ba6h0uIgL76NRETsukAtjYrdo=; b=h6raT1/rKvE/nDP/04xiO0zr5Dix2D5RrQbYfNKLfrHwqAOS44SfrsvJ715GaXBBoS BPSCRT+PtTNUIbZMY8UpF48hEx4Og2jlZNhY1Y7RNa8AMSgZ+KmQq+pIZvZfH9fsN7Jx uEZoFZ6hjQrQSGQ7UOOCqajou5zgNNINuX+xIC0gZ0ev+wGDE17nUYivv1tNfsVEjACv SFZyaGjtOdqYu2FG4ViPJ0pJkJHesDZEx+RffW8HXYOvpHWvcMHjVne2X39NMafHikRd 65j+RPEZM2CcEM2fHYXw2YcFpYiEzDSydCpkKVYv20RMYFtlawi5jmY4uqmDjfz/lfoK gUNA== X-Gm-Message-State: AOJu0YyzpJLkvuytc+ta6ohg/qCB6W2QRTq42/h8hE9txvblUISt3ydb QX7z0Xscw9hv/QNg8Vppz+H7Hd7OKwf82yuWTd6VEyd2IL7o+s3QWJljHW9B5LkoR0PWravkrZi lfha851I2QgAA4CWRnGqd+uUg8+5Wqa8sfFz0LpXsMoFKBz9fP7nUlcFxs6P/fTWT2v/hyrMcha lcn/VVDE2sFUvecFD1mnFAua0g4vCa840PuPTw X-Received: by 2002:a05:620a:c96:b0:787:9720:908 with SMTP id q22-20020a05620a0c9600b0078797200908mr2850949qki.32.1709066923154; Tue, 27 Feb 2024 12:48:43 -0800 (PST) X-Google-Smtp-Source: AGHT+IGveQwFmWtR46zzDGtDpGz/piikDCvV0bbWwxqa6p0Hdr54pRvDcRDaSt9QC+02RvCY/aFlHg== X-Received: by 2002:a05:620a:c96:b0:787:9720:908 with SMTP id q22-20020a05620a0c9600b0078797200908mr2850930qki.32.1709066922626; Tue, 27 Feb 2024 12:48:42 -0800 (PST) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id x12-20020ae9e64c000000b00787ba19ded1sm3945836qkl.3.2024.02.27.12.48.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Feb 2024 12:48:42 -0800 (PST) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] c++: auto(x) partial substitution [PR110025, PR114138] Date: Tue, 27 Feb 2024 15:48:39 -0500 Message-ID: <20240227204839.3396154-1-ppalka@redhat.com> X-Mailer: git-send-email 2.44.0.rc1.15.g4fc51f00ef 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, T_SCC_BODY_TEXT_LINE 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 Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps 13? -- >8 -- In r12-6773-g09845ad7569bac we gave CTAD placeholders a level of 0 and ensured we never replaced them via tsubst. It turns out that autos representing an explicit cast need the same treatment and for the same reason: such autos appear in an expression context and so their level gets easily messed up after partial substitution, leading to premature replacement via an incidental tsubst instead of via do_auto_deduction. This patch fixes this by extending the r12-6773 approach to auto(x) and auto{x}. PR c++/110025 PR c++/114138 gcc/cp/ChangeLog: * cp-tree.h (make_cast_auto): Declare. * parser.cc (cp_parser_functional_cast): Replace a parsed auto with a level-less one via make_cast_auto. * pt.cc (find_parameter_packs_r): Don't treat level-less auto as a type parameter pack. (tsubst) : Generalized CTAD placeholder handling to all level-less autos. (make_cast_auto): Define. (do_auto_deduction): Handle deduction of a level-less non-CTAD auto. gcc/testsuite/ChangeLog: * g++.dg/cpp23/auto-fncast16.C: New test. * g++.dg/cpp23/auto-fncast17.C: New test. * g++.dg/cpp23/auto-fncast18.C: New test. --- gcc/cp/cp-tree.h | 1 + gcc/cp/parser.cc | 11 ++++ gcc/cp/pt.cc | 31 +++++++++- gcc/testsuite/g++.dg/cpp23/auto-fncast16.C | 12 ++++ gcc/testsuite/g++.dg/cpp23/auto-fncast17.C | 15 +++++ gcc/testsuite/g++.dg/cpp23/auto-fncast18.C | 71 ++++++++++++++++++++++ 6 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp23/auto-fncast16.C create mode 100644 gcc/testsuite/g++.dg/cpp23/auto-fncast17.C create mode 100644 gcc/testsuite/g++.dg/cpp23/auto-fncast18.C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 04c3aa6cd91..6f1da1c7bad 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7476,6 +7476,7 @@ extern tree make_decltype_auto (void); extern tree make_constrained_auto (tree, tree); extern tree make_constrained_decltype_auto (tree, tree); extern tree make_template_placeholder (tree); +extern tree make_cast_auto (void); extern bool template_placeholder_p (tree); extern bool ctad_template_p (tree); extern bool unparenthesized_id_or_class_member_access_p (tree); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 3ee9d49fb8e..1e518e6ef51 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -33314,6 +33314,17 @@ cp_parser_functional_cast (cp_parser* parser, tree type) if (!type) type = error_mark_node; + if (TREE_CODE (type) == TYPE_DECL + && is_auto (TREE_TYPE (type))) + type = TREE_TYPE (type); + + if (is_auto (type) + && !AUTO_IS_DECLTYPE (type) + && !PLACEHOLDER_TYPE_CONSTRAINTS (type) + && !CLASS_PLACEHOLDER_TEMPLATE (type)) + /* auto(x) and auto{x} are represented using a level-less auto. */ + type = make_cast_auto (); + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { cp_lexer_set_source_position (parser->lexer); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 2803824d11e..620fe5cdbfa 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -3921,7 +3921,8 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) parameter pack (14.6.3), or the type-specifier-seq of a type-id that is a pack expansion, the invented template parameter is a template parameter pack. */ - if (ppd->type_pack_expansion_p && is_auto (t)) + if (ppd->type_pack_expansion_p && is_auto (t) + && TEMPLATE_TYPE_LEVEL (t) != 0) TEMPLATE_TYPE_PARAMETER_PACK (t) = true; if (TEMPLATE_TYPE_PARAMETER_PACK (t)) parameter_pack_p = true; @@ -16297,9 +16298,14 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } case TEMPLATE_TYPE_PARM: - if (template_placeholder_p (t)) + if (TEMPLATE_TYPE_LEVEL (t) == 0) { + /* Level-less auto must be replaced via do_auto_deduction. */ + gcc_checking_assert (is_auto (t)); tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (t); + if (!tmpl) + return t; + tmpl = tsubst_expr (tmpl, args, complain, in_decl); if (TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM) tmpl = TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (tmpl); @@ -29311,6 +29317,17 @@ template_placeholder_p (tree t) return is_auto (t) && CLASS_PLACEHOLDER_TEMPLATE (t); } +/* Return an auto for an explicit cast, e.g. auto(x) or auto{x}. + Like CTAD placeholders, these have level 0 so that they're not + accidentally replaced via tsubst, and are always directly resolved + via do_auto_deduction. */ + +tree +make_cast_auto () +{ + return make_auto_1 (auto_identifier, true, /*level=*/0); +} + /* Make a "constrained auto" type-specifier. This is an auto or decltype(auto) type with constraints that must be associated after deduction. The constraint is formed from the given concept CON @@ -31213,7 +31230,15 @@ do_auto_deduction (tree type, tree init, tree auto_node, } } - if (TEMPLATE_TYPE_LEVEL (auto_node) == 1) + if (TEMPLATE_TYPE_LEVEL (auto_node) == 0) + { + /* Level-less auto can't be replaced via tsubst, so do it directly. */ + gcc_checking_assert (type == auto_node); + gcc_checking_assert (!TYPE_QUALS (type)); + gcc_checking_assert (TREE_VEC_LENGTH (targs) == 1); + return TREE_VEC_ELT (targs, 0); + } + else if (TEMPLATE_TYPE_LEVEL (auto_node) == 1) /* The outer template arguments are already substituted into type (but we still may have used them for constraint checking above). */; else if (context == adc_unify) diff --git a/gcc/testsuite/g++.dg/cpp23/auto-fncast16.C b/gcc/testsuite/g++.dg/cpp23/auto-fncast16.C new file mode 100644 index 00000000000..e2c13f6b050 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/auto-fncast16.C @@ -0,0 +1,12 @@ +// PR c++/110025 +// { dg-do compile { target c++23 } } + +template +struct A { }; + +template +A f(); + +int main() { + f<0>(); +} diff --git a/gcc/testsuite/g++.dg/cpp23/auto-fncast17.C b/gcc/testsuite/g++.dg/cpp23/auto-fncast17.C new file mode 100644 index 00000000000..25186dfdbf2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/auto-fncast17.C @@ -0,0 +1,15 @@ +// PR c++/110025 +// { dg-do compile { target c++23 } } + +template struct tuple; + +template +using constant_t = int; + +template +using constants_t = tuple...>; + +using ty0 = constants_t<>; +using ty1 = constants_t<1>; +using ty2 = constants_t<1, 2>; +using ty3 = constants_t<1, 2, 3>; diff --git a/gcc/testsuite/g++.dg/cpp23/auto-fncast18.C b/gcc/testsuite/g++.dg/cpp23/auto-fncast18.C new file mode 100644 index 00000000000..bded5caebf4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/auto-fncast18.C @@ -0,0 +1,71 @@ +// PR c++/114138 +// { dg-do compile { target c++23 } } + +namespace std { + template + T&& declval() noexcept requires true; + + template + void declval() noexcept; + + namespace detail { + struct none_such; + template + using none_such_t = none_such; + + template + extern const none_such_t _getter_for; + + template + using _decay_t = decltype(auto(declval())); + + static_assert(__is_same_as(_decay_t, void)); + } + + template + using _result_of_t = decltype(Fn(declval()...)); + + template + using tuple_element_t = _result_of_t>, char(*)[I+1], Tuple>; + + template + struct pair { + First first; + Second second; + }; + + template + inline constexpr bool _is_pair = false; + + template + inline constexpr bool _is_pair> = true; + + template + concept Pair = _is_pair()))>; + + template + requires (I <= 1) + decltype(auto) get(P&& p) noexcept { + if constexpr (I == 0) { + return (static_cast(p).first); + } else { + return (static_cast(p).second); + } + } + + namespace detail { + inline constexpr auto _pair_getter = + [](char(*)[J], Pair&& p) noexcept -> decltype(auto) { + return std::get(static_cast(p)); + }; + + template + inline constexpr auto _getter_for> = _pair_getter; + } + +} + +int main() { + static_assert(__is_same_as(int&, std::tuple_element_t<0, std::pair&>)); + static_assert(__is_same_as(float&&, std::tuple_element_t<1, std::pair&&>)); +}