Thanks for the patch!
Please review https://gcc.gnu.org/contribute.html for more details of
the format patches should have. In particular, you don't seem to have a
copyright assignment on file with the FSF, so you'll need to either do
that or certify that the contribution is under the DCO.
Also, you need a component tag (c++:) in the subject line, and ChangeLog
entries in the commit message. Note what contribute.html says about git
gcc-commit-mklog, which makes that a lot simpler.
On 5/1/24 18:52, Seyed Sajad Kahani wrote:
When deducing auto for `adc_return_type`, `adc_variable_type`, and
`adc_decomp_type` contexts (at the usage time), we try to resolve the outermost
template arguments to be used for satisfaction. This is done by one of the
following, depending on the scope:
1. Checking the `DECL_TEMPLATE_INFO` of the current function scope and
extracting DECL_TI_ARGS from it for function scope deductions (pt.cc:31236).
2. Checking the `DECL_TEMPLATE_INFO` of the declaration (alongside with other
conditions) for non-function scope variable declaration deductions
(decl.cc:8527).
Then, we do not retrieve the deeper layers of the template arguments; instead,
we fill the missing levels with dummy levels (pt.cc:31260).
The problem (that is shown in PR114915) is that we do not consider the case
where the deduction happens in a template specialization scope. In this case,
the type is not dependent on the outermost template arguments (which are the
specialization arguments). Yet, we still resolve the outermost template
arguments, and then the number of layers in the template arguments exceeds the
number of levels in the type. This causes the missing levels to be negative.
This leads to the rejection of valid code and ICEs (like segfault) in the
release mode. In the debug mode, it is possible to show as an assertion failure
(when creating a tree_vec with a negative size).
The code that generates the issue is added to the test suite as
`g++.dg/cpp2a/concepts-placeholder14.C`.
This testcase could use more cases, like variable template
specialization (both full and partial) and member functions where not
all enclosing classes are fully specialized.
This patch fixes the issue by checking that the template usage, whose arguments
are going to be used for satisfaction, is not a partial or explicit
specialization (and therefore it is an implicit or explicit instantiation).
This check is done in the two only places that affect the `outer_targs` for the
mentioned contexts.
It seems like we want a function to use instead of DECL_TI_ARGS to get
the args for parameters that are actually in scope in the definition
that we're substituting into. In the case of a full specialization,
that would be NULL_TREE, but it's more complicated for partial
specializations.
This function should probably go after outer_template_args in pt.cc.
One might ask why this is not implemented as a simple `missing_level > 0`
check. The reason is that the recovery from the negative `missing_levels` will not
be easy, and it is not clear how to recover from it. Therefore, it is better to
prevent it from happening.
But you still have that check in the patch. Would it be better as an
assert?
Thanks,
Jason