c++: Return only in-scope tparms in keep_template_parm [PR95310]
authorPatrick Palka <ppalka@redhat.com>
Tue, 22 Sep 2020 20:26:52 +0000 (16:26 -0400)
committerPatrick Palka <ppalka@redhat.com>
Tue, 22 Sep 2020 20:26:52 +0000 (16:26 -0400)
commitd6587211c02c4e2566c4e545c09757f3fbb7adab
tree5035066819fd8576ea18332ad6eb5ded6a1fd078
parentc4e4e163c79ca3fca265b85f44b869cb54e802b3
c++: Return only in-scope tparms in keep_template_parm [PR95310]

In the testcase below, the dependent specializations iter_reference_t<F>
and iter_reference_t<Out> share the same tree due to specialization
caching.  So when find_template_parameters walks through the
requires-expression (as part of normalization), it sees and includes the
out-of-scope template parameter F in the list of template parameters
it found within the requires-expression (along with Out and N).

From a correctness perspective this is harmless since the parameter mapping
routines only care about the level and index of each parameter, so F is
no different from Out in that sense.  And it's also harmless that two
parameters in the parameter mapping have the same level and index.

But having both Out and F in the parameter mapping means extra work for
hash_atomic_constrant, tsubst_parameter_mapping and get_mapped_args; and
it also means we print this irrelevant template parameter in the
testcase's diagnostics (via pp_cxx_parameter_mapping):

  in requirements with ‘Out o’ [with N = (const int&)&a; F = const int*; Out = const int*]

This patch makes keep_template_parm return only in-scope template
parameters by looking into ctx_parms for the corresponding in-scope
one, through a new helper function corresponding_template_parameter.

(That we sometimes print irrelevant template parameters in diagnostics
is also the subject of PR99 and PR66968, so the above diagnostic issue
could likely be fixed in a more general way, but this targeted fix to
keep_template_parm is perhaps worthwhile on its own.)

gcc/cp/ChangeLog:

PR c++/95310
* pt.c (corresponding_template_parameter): Define.
(keep_template_parm): Use it to adjust the given template
parameter to the corresponding in-scope one from ctx_parms.

gcc/testsuite/ChangeLog:

PR c++/95310
* g++.dg/concepts/diagnostic15.C: New test.
gcc/cp/pt.c
gcc/testsuite/g++.dg/concepts/diagnostic15.C [new file with mode: 0644]