pt.c (coerce_template_parms): Refactor.
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 31 Jul 2003 09:16:31 +0000 (09:16 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 31 Jul 2003 09:16:31 +0000 (09:16 +0000)
cp:
* pt.c (coerce_template_parms): Refactor.
(fn_type_unification): Increment processing_template_decl when
tsubsting an incomplete set of explicit args.
testsuite:
* g++.dg/template/explicit3.C: New.
* g++.dg/template/explicit4.C: New.
* g++.dg/template/explicit5.C: New.

From-SVN: r69995

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/explicit3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/explicit4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/explicit5.C [new file with mode: 0644]

index 2f96f95..bc4eaf7 100644 (file)
@@ -1,5 +1,9 @@
 2003-07-31  Nathan Sidwell  <nathan@codesourcery.com>
 
+       * pt.c (coerce_template_parms): Refactor.
+       (fn_type_unification): Increment processing_template_decl when
+       tsubsting an incomplete set of explicit args.
+
        PR c++/11347
        * pt.c (instantiate_class_template): Increment
        processing_template_decl around the tsubst of a template member
index a1f57dc..9661ea3 100644 (file)
@@ -3639,24 +3639,16 @@ coerce_template_parms (tree parms,
        }
       else if (i < nargs)
        arg = TREE_VEC_ELT (inner_args, i);
-      else
-        /* If no template argument was supplied, look for a default
-          value.  */
+      else if (require_all_arguments)
+       /* There must be a default arg in this case. */
        arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
                                   complain, in_decl);
-
-      /* Now, convert the Ith argument, as necessary.  */
-      if (arg == NULL_TREE)
-       /* We're out of arguments.  */
-       {
-         my_friendly_assert (!require_all_arguments, 0);
-         break;
-       }
-      else if (arg == error_mark_node)
-       {
-         error ("template argument %d is invalid", i + 1);
-         arg = error_mark_node;
-       }
+      else
+       break;
+      
+      my_friendly_assert (arg, 20030727);
+      if (arg == error_mark_node)
+       error ("template argument %d is invalid", i + 1);
       else 
        arg = convert_template_argument (TREE_VALUE (parm), 
                                         arg, new_args, complain, i,
@@ -8578,6 +8570,7 @@ fn_type_unification (tree fn,
         template results in an invalid type, type deduction fails.  */
       int i;
       tree converted_args;
+      bool incomplete;
 
       converted_args
        = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn), 
@@ -8586,12 +8579,22 @@ fn_type_unification (tree fn,
       if (converted_args == error_mark_node)
        return 1;
 
+      /* Substitute the explicit args into the function type.  This is
+         necessary so that, for instance, explicitly declared function
+         arguments can match null pointed constants.  If we were given
+         an incomplete set of explicit args, we must not do semantic
+         processing during substitution as we could create partial
+         instantiations.  */
+      incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
+      processing_template_decl += incomplete;
       fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE);
+      processing_template_decl -= incomplete;
+      
       if (fntype == error_mark_node)
        return 1;
 
       /* Place the explicitly specified arguments in TARGS.  */
-      for (i = 0; i < TREE_VEC_LENGTH (targs); i++)
+      for (i = NUM_TMPL_ARGS (converted_args); i--;)
        TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i);
     }
      
index fb4910b..b3137c3 100644 (file)
@@ -1,5 +1,9 @@
 2003-07-31  Nathan Sidwell  <nathan@codesourcery.com>
 
+       * g++.dg/template/explicit3.C: New.
+       * g++.dg/template/explicit4.C: New.
+       * g++.dg/template/explicit5.C: New.
+
        PR c++/11347
        * g++.dg/template/memtmpl1.C: New.
 
diff --git a/gcc/testsuite/g++.dg/template/explicit3.C b/gcc/testsuite/g++.dg/template/explicit3.C
new file mode 100644 (file)
index 0000000..49d0689
--- /dev/null
@@ -0,0 +1,22 @@
+// { dg-do compile }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 27 Jul 2003 <nathan@codesourcery.com>
+
+// Failed to spot specialization using a template-id expr
+
+template <int n> class A {};
+template <int m> class R {};
+
+template <int n, int x> struct Trait { enum {m = n}; };
+
+template <int n, int x> R<Trait<n,x>::m> f(A<x>);
+template <> R<Trait<1,1>::m> f<1>(A<1>) {return R<1>();}
+
+void Baz ()
+{
+  R<Trait<1,1>::m> (*ptr) (A<1>);
+
+  ptr = &f<1>;
+  
+}
diff --git a/gcc/testsuite/g++.dg/template/explicit4.C b/gcc/testsuite/g++.dg/template/explicit4.C
new file mode 100644 (file)
index 0000000..3953f8f
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-do compile }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 27 Jul 2003 <nathan@codesourcery.com>
+
+// Failed to spot specialization using a template-id expr
+
+template <typename n> class A {};
+template <int m> class R {};
+
+template <int n, int x> struct Trait { enum {m = n}; };
+
+template <typename n, typename x> R<Trait<1,1>::m> f(A<x>);
+template <> R<Trait<1,1>::m> f<int>(A<int>) {return R<1>();}
diff --git a/gcc/testsuite/g++.dg/template/explicit5.C b/gcc/testsuite/g++.dg/template/explicit5.C
new file mode 100644 (file)
index 0000000..a0e3133
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-do compile }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 27 Jul 2003 <nathan@codesourcery.com>
+
+// Failed to spot specialization using a template-id expr
+
+template <typename n> class A {};
+template <int m> class R {};
+
+template <typename n, typename x> struct Trait { enum {m = sizeof (n)}; };
+
+template <typename n, typename x> R<Trait<n,x>::m> f(A<x>);
+template <> R<Trait<char,char>::m> f<char>(A<char>) {return R<1>();}