Patchwork C++ PATCH for c++/44629 (ICE with function template as non-type template argument)

login
register
mail settings
Submitter Jason Merrill
Date March 9, 2011, 5:56 p.m.
Message ID <4D77BF68.1060002@redhat.com>
Download mbox | patch
Permalink /patch/86149/
State New
Headers show

Comments

Jason Merrill - March 9, 2011, 5:56 p.m.
In this testcase, we have a function template used as an argument for a 
function pointer template parameter.  This causes unify to abort because 
an OVERLOAD doesn't satisfy EXPR_P.  14.8.2.5 lists an overloaded 
function given as a function argument as a non-deduced context, so it 
seems reasonable to treat one given as a template argument as 
non-deduced as well.

The ABI is silent on how to mangle this, and EDG currently does 
something strange, so I'm not going to add mangling in 4.6; as a result, 
the testcase will get a sorry from the mangler, but that's better than 
an ICE.

Tested x86_64-pc-linux-gnu, applied to trunk, 4.4, 4.5.
commit 5faa2c811748d00cbee57ad0e5c991549099b95a
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Mar 8 21:44:29 2011 -0500

    	PR c++/44629
    	* pt.c (unify): An unresolved overload is a nondeduced context.

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2ca2cd0..ac91698 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15688,6 +15688,9 @@  unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       return 1;
 
     default:
+      /* An unresolved overload is a nondeduced context.  */
+      if (type_unknown_p (parm))
+	return 0;
       gcc_assert (EXPR_P (parm));
 
       /* We must be looking at an expression.  This can happen with
diff --git a/gcc/testsuite/g++.dg/template/nontype22.C b/gcc/testsuite/g++.dg/template/nontype22.C
new file mode 100644
index 0000000..f2c8c46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/nontype22.C
@@ -0,0 +1,11 @@ 
+// PR c++/44629
+// The proper mangling is unclear.
+
+template<typename T> int cmp1(T a, T b);
+template<typename T, int (*cmp)(T, T) = cmp1> struct A { };
+template <typename T> void f (A<T> &); // { dg-bogus "" "" { xfail *-*-* } }
+void g()
+{
+  A<char> a;
+  f(a);
+}