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

Reply via email to