Commit ffd49b19 by Nathan Sidwell Committed by Nathan Sidwell

pt.c (coerce_template_parms): Refactor.

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
parent fb5ce3c9
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
......
......@@ -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);
}
......
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.
......
// { 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>;
}
// { 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>();}
// { 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>();}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment