Bug 56377

Summary: [4.8 Regression] <missing> template args in substitution-failure diagnostics
Product: gcc Reporter: Paul Smith <pl.smith.mail>
Component: c++Assignee: Jason Merrill <jason>
Status: RESOLVED FIXED    
Severity: minor CC: jakub, jason
Priority: P1 Keywords: diagnostic
Version: 4.8.0   
Target Milestone: 4.8.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2013-02-18 00:00:00

Description Paul Smith 2013-02-18 16:04:52 UTC
When a candidate function for which substituion failed is listed in a diagnostic, if the failure stems from a template parameter that have an explicit argument, the explicit arguments are listed as <missing>.

For example:

template <typename T>
typename T::type f();

int main () {
  f<int>();
}

Produces (4.8, no flags):

test.cpp: In function ג€˜int main()ג€™:
test.cpp:5:10: error: no matching function for call to 'f()'
   f<int>();
          ^
test.cpp:5:10: note: candidate is:
test.cpp:2:18: note: template<class T> typename T::type f()
 typename T::type f();
                  ^
test.cpp:2:18: note:   template argument deduction/substitution failed:
  *************
test.cpp: In substitution of 'template<class T> typename T::type f() [with T = <missing>]':
  *************
test.cpp:5:10:   required from here
test.cpp:2:18: error: 'int' is not a class, struct, or union type

In 4.7 it is "[with T = int]".
Comment 1 Paul Smith 2013-02-18 16:12:00 UTC
Looks like this was introduced in rev. 190664, with the merging of 'deduction_tsubst_fntype' into 'fn_type_unification'.

The instantiation context is constructed with 'targs' as the vector of template arguments, which is still empty when substituting the explicit arguments into the function type the first time. This can be fixed by either constructing the instantiation context using 'explicit_targs' when non-null, or by copying 'explicit_targs' into 'targs' before the substitution.
Comment 2 Jakub Jelinek 2013-02-19 09:58:16 UTC
Yeah, diff between r190663 and r190664 output is:
-pr56377.C: In substitution of ‘template<class T> typename T::type f() [with T = int]’:
+pr56377.C: In substitution of ‘template<class T> typename T::type f() [with T = <missing>]’:
Comment 3 Jason Merrill 2013-02-22 22:24:40 UTC
Author: jason
Date: Fri Feb 22 22:24:27 2013
New Revision: 196230

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196230
Log:
	PR c++/56377
	* pt.c (fn_type_unification): Use explicit args in template
	instantiation context.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
Comment 4 Jason Merrill 2013-02-23 01:59:20 UTC
Fixed.
Comment 5 Paul Smith 2013-02-23 15:15:47 UTC
There can still be <missing> arguments before the substitution:

template <int N>
void f() {
  f<N + 1>();
}

int main() {
  f<0>();
}

Output:

test.cpp:3:11: error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) substituting ‘template<int N> void f() [with int N = <missing>]’
  f<N + 1>();
           ^
...
Comment 6 Jason Merrill 2013-02-26 04:28:04 UTC
Author: jason
Date: Tue Feb 26 04:27:51 2013
New Revision: 196275

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196275
Log:
	PR c++/56377
	* pt.c (fn_type_unification): Wait to call push_tinst_level until
	we know what args we're looking at.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
Comment 7 Jason Merrill 2013-02-26 04:29:17 UTC
Should really be fixed now.