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

Reply via email to