Bug 56377 - [4.8 Regression] <missing> template args in substitution-failure diagnostics
Summary: [4.8 Regression] <missing> template args in substitution-failure diagnostics
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.0
: P1 minor
Target Milestone: 4.8.0
Assignee: Jason Merrill
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2013-02-18 16:04 UTC by Paul Smith
Modified: 2013-02-26 04:29 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-02-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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.