This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for minor pt.c cleanup
- To: egcs-patches at cygnus dot com
- Subject: C++ PATCH for minor pt.c cleanup
- From: Mark Mitchell <mark at markmitchell dot com>
- Date: Tue, 2 Mar 1999 23:46:36 -0800
- Reply-to: mark at markmitchell dot com
This patch just simplifies code a little in the wake of recent
changes. As a bonus, there's a fix for a crash involving invalid
typename types.
--
Mark Mitchell mark@markmitchell.com
Mark Mitchell Consulting http://www.markmitchell.com
1999-03-02 Mark Mitchell <mark@markmitchell.com>
* cp-tree.h (determine_specialization): Don't declare.
* pt.c (determine_specialization): Make it static. Eliminate
complain parameter. Note that decl is always non-NULL now, and
simplify accordingly.
(tsubst): Catch illegal typename substitutions.
Index: crash30.C
===================================================================
RCS file: crash30.C
diff -N crash30.C
*** /dev/null Sat Dec 5 20:30:03 1998
--- crash30.C Tue Mar 2 23:43:25 1999
***************
*** 0 ****
--- 1,15 ----
+ // Build don't link:
+
+ extern "C" int printf(const char *, ...);
+ template <class T> struct A {
+ typedef typename T::X B; // ERROR - not a class
+ A(double);
+ };
+
+ template <class T> void xxx(typename A<T>::B);
+
+ template <class T> struct B {
+ friend void xxx<T>(T); // ERROR - does not match any template
+ };
+
+ template struct B<double>; // ERROR -
Index: testsuite/cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.199
diff -c -p -r1.199 cp-tree.h
*** cp-tree.h 1999/02/21 16:38:10 1.199
--- cp-tree.h 1999/03/02 21:40:25
*************** extern void reset_specialization
*** 3053,3059 ****
extern void end_specialization PROTO((void));
extern void begin_explicit_instantiation PROTO((void));
extern void end_explicit_instantiation PROTO((void));
- extern tree determine_specialization PROTO((tree, tree, tree *, int, int));
extern tree check_explicit_specialization PROTO((tree, tree, int, int));
extern tree process_template_parm PROTO((tree, tree));
extern tree end_template_parm_list PROTO((tree));
--- 3053,3058 ----
Index: testsuite/cp/pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.264
diff -c -p -r1.264 pt.c
*** pt.c 1999/02/21 16:38:19 1.264
--- pt.c 1999/03/02 21:40:44
*************** static tree get_template_base PROTO((tre
*** 148,153 ****
--- 148,154 ----
static tree try_class_unification PROTO((tree, tree, tree, tree));
static int coerce_template_template_parms PROTO((tree, tree, int,
tree, tree));
+ static tree determine_specialization PROTO((tree, tree, tree *, int));
/* We use TREE_VECs to hold template arguments. If there is only one
level of template arguments, then the TREE_VEC contains the
*************** print_candidates (fns)
*** 917,934 ****
are output in a newly created vector *TARGS_OUT.
If it is impossible to determine the result, an error message is
! issued, unless COMPLAIN is 0. In any case, error_mark_node is
! returned to indicate failure. */
tree
determine_specialization (template_id, decl, targs_out,
! need_member_template,
! complain)
tree template_id;
tree decl;
tree* targs_out;
int need_member_template;
- int complain;
{
tree fn;
tree fns;
--- 918,932 ----
are output in a newly created vector *TARGS_OUT.
If it is impossible to determine the result, an error message is
! issued. The error_mark_node is returned to indicate failure. */
tree
determine_specialization (template_id, decl, targs_out,
! need_member_template)
tree template_id;
tree decl;
tree* targs_out;
int need_member_template;
{
tree fn;
tree fns;
*************** determine_specialization (template_id, d
*** 973,982 ****
/* This is just an ordinary non-member function. Nothing can
be a specialization of that. */
continue;
- else if (!decl)
- /* When there's no DECL to match, we know we're looking for
- non-members. */
- continue;
else
{
tree decl_arg_types;
--- 971,976 ----
*************** determine_specialization (template_id, d
*** 1010,1034 ****
continue;
}
! if (decl == NULL_TREE)
! {
! /* Unify against ourselves to make sure that the args we have
! make sense and there aren't any undeducible parms. It's OK if
! not all the parms are specified; they might be deduced
! later. */
! targs = get_bindings_overload (tmpl, DECL_RESULT (tmpl),
! explicit_targs);
! if (uses_template_parms (targs))
! /* We couldn't deduce all the arguments. */
! continue;
! }
! else
! /* See whether this function might be a specialization of this
! template. */
! targs = get_bindings (tmpl, decl, explicit_targs);
if (!targs)
! /* Wwe cannot deduce template arguments that when used to
specialize TMPL will produce DECL. */
continue;
--- 1004,1015 ----
continue;
}
! /* See whether this function might be a specialization of this
! template. */
! targs = get_bindings (tmpl, decl, explicit_targs);
if (!targs)
! /* We cannot deduce template arguments that when used to
specialize TMPL will produce DECL. */
continue;
*************** determine_specialization (template_id, d
*** 1036,1042 ****
templates = scratch_tree_cons (targs, tmpl, templates);
}
! if (decl && templates && TREE_CHAIN (templates))
{
/* We have:
--- 1017,1023 ----
templates = scratch_tree_cons (targs, tmpl, templates);
}
! if (templates && TREE_CHAIN (templates))
{
/* We have:
*************** determine_specialization (template_id, d
*** 1079,1099 ****
if (templates == NULL_TREE && candidates == NULL_TREE)
{
! if (complain)
! cp_error_at ("template-id `%D' for `%+D' does not match any template declaration",
! template_id, decl);
return error_mark_node;
}
else if ((templates && TREE_CHAIN (templates))
! || (candidates && TREE_CHAIN (candidates)))
{
! if (complain)
! {
! cp_error_at ("ambiguous template specialization `%D' for `%+D'",
! template_id, decl);
! chainon (candidates, templates);
! print_candidates (candidates);
! }
return error_mark_node;
}
--- 1060,1077 ----
if (templates == NULL_TREE && candidates == NULL_TREE)
{
! cp_error_at ("template-id `%D' for `%+D' does not match any template declaration",
! template_id, decl);
return error_mark_node;
}
else if ((templates && TREE_CHAIN (templates))
! || (candidates && TREE_CHAIN (candidates))
! || (templates && candidates))
{
! cp_error_at ("ambiguous template specialization `%D' for `%+D'",
! template_id, decl);
! chainon (candidates, templates);
! print_candidates (candidates);
return error_mark_node;
}
*************** check_explicit_specialization (declarato
*** 1445,1452 ****
declaration. */
tmpl = determine_specialization (declarator, decl,
&targs,
! member_specialization,
! 1);
if (!tmpl || tmpl == error_mark_node)
/* We couldn't figure out what this declaration was
--- 1423,1429 ----
declaration. */
tmpl = determine_specialization (declarator, decl,
&targs,
! member_specialization);
if (!tmpl || tmpl == error_mark_node)
/* We couldn't figure out what this declaration was
*************** tsubst_friend_function (decl, args)
*** 4366,4373 ****
new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
tmpl = determine_specialization (template_id, new_friend,
&new_args,
! /*need_member_template=*/0,
! /*complain=*/1);
new_friend = instantiate_template (tmpl, new_args);
goto done;
}
--- 4343,4349 ----
new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
tmpl = determine_specialization (template_id, new_friend,
&new_args,
! /*need_member_template=*/0);
new_friend = instantiate_template (tmpl, new_args);
goto done;
}
*************** tsubst (t, args, complain, in_decl)
*** 6039,6046 ****
Type deduction may fail for any of the following
reasons:
! Attempting to create an array with a size that is
! zero or negative. */
if (complain)
cp_error ("creating array with size `%E'", max);
--- 6015,6022 ----
Type deduction may fail for any of the following
reasons:
! Attempting to create an array with a size that is
! zero or negative. */
if (complain)
cp_error ("creating array with size `%E'", max);
*************** tsubst (t, args, complain, in_decl)
*** 6403,6418 ****
if (ctx == error_mark_node || f == error_mark_node)
return error_mark_node;
! /* Normally, make_typename_type does not require that the CTX
! have complete type in order to allow things like:
! template <class T> struct S { typename S<T>::X Y; };
! But, such constructs have already been resolved by this
! point, so here CTX really should have complete type, unless
! it's a partial instantiation. */
! if (!uses_template_parms (ctx) && !TYPE_BEING_DEFINED (ctx))
! {
ctx = complete_type (ctx);
if (!TYPE_SIZE (ctx))
{
--- 6379,6401 ----
if (ctx == error_mark_node || f == error_mark_node)
return error_mark_node;
! if (!IS_AGGR_TYPE (ctx))
! {
! if (complain)
! cp_error ("`%T' is not a class, struct, or union type",
! ctx);
! return error_mark_node;
! }
! else if (!uses_template_parms (ctx) && !TYPE_BEING_DEFINED (ctx))
! {
! /* Normally, make_typename_type does not require that the CTX
! have complete type in order to allow things like:
! template <class T> struct S { typename S<T>::X Y; };
! But, such constructs have already been resolved by this
! point, so here CTX really should have complete type, unless
! it's a partial instantiation. */
ctx = complete_type (ctx);
if (!TYPE_SIZE (ctx))
{