From: Jason Merrill <jason@redhat.com>
To: Patrick Palka <ppalka@redhat.com>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++: NTTP constraint depending on outer args [PR109160]
Date: Wed, 29 Mar 2023 16:28:00 -0400 [thread overview]
Message-ID: <a07656e7-2c98-0162-5db4-ccfc55c17c71@redhat.com> (raw)
In-Reply-To: <20230317152629.3944138-1-ppalka@redhat.com>
On 3/17/23 11:26, Patrick Palka wrote:
> Here we're crashing during satisfaction for the NTTP 'C<B> auto' from
> do_auto_deduction ultimately because convert_template_argument / unify
> don't pass all outer template arguments to do_auto_deduction, and during
> satisfaction we need to know all arguments. While these callers do
> pass some outer arguments, they are only sufficient to properly
> substitute the 'auto' and are not necessarily the complete set.
>
> Fortunately it seems it's possible to obtain the full set of outer
> arguments from these callers via convert_template_argument's IN_DECL
> parameter and unify's TPARMS parameter. So this patch adds a TMPL
> parameter to do_auto_deduction, used only during adc_unify deduction,
> which contains the (partially instantiated) template corresponding to
> this auto and from which we can obtain all outer template arguments for
> satisfaction.
>
> This patch also adjusts the IN_DECL argument passed to
> coerce_template_parms from tsubst_decl so that we could in turn safely
> assume convert_template_argument's IN_DECL is always a TEMPLATE_DECL,
> and thus could pass it as-is to do_auto_deduction. (tsubst_decl seems
> to be the only caller that passes a non-empty non-template IN_DECL to
> coerce_template_parms.)
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk/12?
>
> PR c++/109160
>
> gcc/cp/ChangeLog:
>
> * cp-tree.h (do_auto_deduction): Add defaulted TMPL parameter.
> * pt.cc (convert_template_argument): Pass IN_DECL as TMPL to
> do_auto_deduction.
> (tsubst_decl) <case VAR_/TYPE_DECL>: Pass TMPL instead of T as
> IN_DECL to coerce_template_parms.
> (unify) <case TEMPLATE_PARM_INDEX>: Pass the corresponding
> template as TMPL to do_auto_deduction.
> (do_auto_deduction): Document default arguments. Use TMPL
> to obtain a full set of template arguments for satisfaction
> in the adc_unify case.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/cpp2a/concepts-placeholder12.C: New test.
> ---
> gcc/cp/cp-tree.h | 3 +-
> gcc/cp/pt.cc | 30 ++++++++++++++-----
> .../g++.dg/cpp2a/concepts-placeholder12.C | 29 ++++++++++++++++++
> 3 files changed, 53 insertions(+), 9 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C
>
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index dfc1c845768..e7190c5cc62 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -7324,7 +7324,8 @@ extern tree do_auto_deduction (tree, tree, tree,
> auto_deduction_context
> = adc_unspecified,
> tree = NULL_TREE,
> - int = LOOKUP_NORMAL);
> + int = LOOKUP_NORMAL,
> + tree = NULL_TREE);
> extern tree type_uses_auto (tree);
> extern tree type_uses_auto_or_concept (tree);
> extern void append_type_to_template_for_access_check (tree, tree, tree,
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index ddbd73371b9..6400b686a58 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -8638,7 +8638,7 @@ convert_template_argument (tree parm,
> else if (tree a = type_uses_auto (t))
> {
> t = do_auto_deduction (t, arg, a, complain, adc_unify, args,
> - LOOKUP_IMPLICIT);
> + LOOKUP_IMPLICIT, in_decl);
> if (t == error_mark_node)
> return error_mark_node;
> }
> @@ -15243,7 +15243,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
> the template. */
> argvec = (coerce_template_parms
> (DECL_TEMPLATE_PARMS (gen_tmpl),
> - argvec, t, complain));
> + argvec, tmpl, complain));
> if (argvec == error_mark_node)
> RETURN (error_mark_node);
> hash = spec_hasher::hash (gen_tmpl, argvec);
> @@ -24655,7 +24655,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
> if (tree a = type_uses_auto (tparm))
> {
> tparm = do_auto_deduction (tparm, arg, a,
> - complain, adc_unify, targs);
> + complain, adc_unify, targs,
> + LOOKUP_NORMAL,
> + TPARMS_PRIMARY_TEMPLATE (tparms)); > if (tparm == error_mark_node)
> return 1;
> }
> @@ -30643,13 +30645,20 @@ unparenthesized_id_or_class_member_access_p (tree init)
> adc_requirement contexts to communicate the necessary template arguments
> to satisfaction. OUTER_TARGS is ignored in other contexts.
>
> - For partial-concept-ids, extra args may be appended to the list of deduced
> - template arguments prior to determining constraint satisfaction. */
> + Additionally for adc_unify contexts TMPL is the template for which this
> + auto is a template parameter type.
> +
> + For partial-concept-ids, extra args from OUTER_TARGS, TMPL and the current
> + scope may be appended to the list of deduced template arguments prior to
> + determining constraint satisfaction as appropriate. */
>
> tree
> do_auto_deduction (tree type, tree init, tree auto_node,
> - tsubst_flags_t complain, auto_deduction_context context,
> - tree outer_targs, int flags)
> + tsubst_flags_t complain /* = tf_warning_or_error */,
> + auto_deduction_context context /* = adc_unspecified */,
> + tree outer_targs /* = NULL_TREE */,
> + int flags /* = LOOKUP_NORMAL */,
> + tree tmpl /* = NULL_TREE */)
> {
> if (init == error_mark_node)
> return error_mark_node;
> @@ -30839,7 +30848,12 @@ do_auto_deduction (tree type, tree init, tree auto_node,
> }
> }
>
> - tree full_targs = add_to_template_args (outer_targs, targs);
> + tree full_targs = outer_targs;
> +
> + if (context == adc_unify)
> + full_targs = add_outermost_template_args (tmpl, full_targs);
I recently noticed that sometimes TPARMS_PRIMARY_TEMPLATE isn't set
properly for partially instantiated template template parameters, so
let's make this more robust by only doing this if tmpl is non-null,
maybe with a checking_assert that it is. OK with that change.
> + full_targs = add_to_template_args (full_targs, targs);
>
> /* HACK: Compensate for callers not always communicating all levels of
> outer template arguments by filling in the outermost missing levels
> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C
> new file mode 100644
> index 00000000000..3d4d138720e
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C
> @@ -0,0 +1,29 @@
> +// PR c++/109160
> +// { dg-do compile { target c++20 } }
> +
> +template<class T, bool B>
> +concept C = B;
> +
> +template<int> struct X { };
> +
> +template<bool B>
> +struct A {
> + template<C<B> auto V> static void f();
> + template<C<B> auto V> static void g(X<V>);
> + template<C<B> auto V> static inline int value = V;
> + template<C<B> auto V> struct D { };
> +};
> +
> +int main() {
> + A<true>::f<0>();
> + A<false>::f<0>(); // { dg-error "no match|constraints" }
> +
> + A<true>::g(X<0>{});
> + A<false>::g(X<0>{}); // { dg-error "no match|constraints" }
> +
> + bool v1 = A<true>::value<0>;
> + bool v2 = A<false>::value<0>; // { dg-error "constraints" }
> +
> + A<true>::D<0> d1;
> + A<false>::D<0> d2; // { dg-error "constraints" }
> +}
next prev parent reply other threads:[~2023-03-29 20:28 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-17 15:26 Patrick Palka
2023-03-17 15:44 ` Patrick Palka
2023-03-27 17:54 ` Patrick Palka
2023-03-29 20:28 ` Jason Merrill [this message]
2023-04-01 16:04 ` Patrick Palka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a07656e7-2c98-0162-5db4-ccfc55c17c71@redhat.com \
--to=jason@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=ppalka@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).