On 9/25/21 15:15, nick huang wrote:
Why doesn't the PR92010 fix address these testcases as well?
3. PR92010 creates new functions of "rebuild_function_or_method_type" and by
using gdb to trace PR101402 code as following:
template<class T> struct A {
typedef T arr[3];
};
template<class T> void f(const typename A<T>::arr) { } // #1
template void f<int>(const A<int>::arr); // #2
I added some print function declaration code before and after calling
"maybe_rebuild_function_decl_type" to print out its parameter "r" which is function
declaration inside "tsubst_function_decl".
Here is the result:
a) Before calling, the function declaration is "void f(int*)" and after calling, it is adjusted to correct one as
"void f(const int*)". However, after this line "SET_DECL_IMPLICIT_INSTANTIATION (r);", it fallback to original
dependent type as "void f(typename A<T>::arr) [with T = int; typename A<T>::arr = int [3]]" till end. This
completely defeats the purpose of template substitution effort.
That's just an artifact of (bug in) how we print it as template+args
once it's marked as an instantiation; the actual type of the function
returned from tsubst_function_decl is still void (const int*).
The problem seems to come when we get back to determine_specialization,
where we have
// Then, try to form the new function type.
=> insttype = tsubst (TREE_TYPE (fn), targs, tf_fndecl_type, NULL_TREE);
which does the wrong substitution again, and not the correct one from
maybe_rebuild_function_decl_type.
Both this substitution check and the constraint check just before it
seem redundant with the checks we already did in fn_type_unification, so
the right fix may be to just remove the broken ones here in
determine_specialization.
Jason