diff options
author | Mark Mitchell <mark@markmitchell.com> | 1999-03-02 23:44:49 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-03-02 23:44:49 +0000 |
commit | bf8f3f938b8d0a98a0f0f7b19bd9297daf95d9bd (patch) | |
tree | 7085745fd31bd2a1d210951b137012b5c9673124 /gcc | |
parent | 642b32a58a733af03e442b602612666254d94677 (diff) | |
download | gcc-bf8f3f938b8d0a98a0f0f7b19bd9297daf95d9bd.zip gcc-bf8f3f938b8d0a98a0f0f7b19bd9297daf95d9bd.tar.gz gcc-bf8f3f938b8d0a98a0f0f7b19bd9297daf95d9bd.tar.bz2 |
cp-tree.h (determine_specialization): Don't declare.
* 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.
From-SVN: r25554
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/pt.c | 87 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/crash30.C | 15 |
4 files changed, 55 insertions, 53 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3a7d369..e509858 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 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. + * decl.c (maybe_push_to_top_level): Always call push_cp_function_context. (pop_from_top_level): Always call pop_cp_function_context. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 59a067e..935f8f9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3053,7 +3053,6 @@ extern void reset_specialization PROTO((void)); 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)); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0f6d228..a79b027 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -148,6 +148,7 @@ static tree get_template_base PROTO((tree, tree, tree, tree)); 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 @@ -917,18 +918,15 @@ print_candidates (fns) 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. */ + issued. The error_mark_node is returned to indicate failure. */ tree determine_specialization (template_id, decl, targs_out, - need_member_template, - complain) + need_member_template) tree template_id; tree decl; tree* targs_out; int need_member_template; - int complain; { tree fn; tree fns; @@ -973,10 +971,6 @@ determine_specialization (template_id, decl, targs_out, /* 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; @@ -1010,25 +1004,12 @@ determine_specialization (template_id, decl, targs_out, 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); + /* 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 + /* We cannot deduce template arguments that when used to specialize TMPL will produce DECL. */ continue; @@ -1036,7 +1017,7 @@ determine_specialization (template_id, decl, targs_out, templates = scratch_tree_cons (targs, tmpl, templates); } - if (decl && templates && TREE_CHAIN (templates)) + if (templates && TREE_CHAIN (templates)) { /* We have: @@ -1079,21 +1060,18 @@ determine_specialization (template_id, decl, targs_out, 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); + 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))) + || (candidates && TREE_CHAIN (candidates)) + || (templates && candidates)) { - if (complain) - { - cp_error_at ("ambiguous template specialization `%D' for `%+D'", - template_id, decl); - chainon (candidates, templates); - print_candidates (candidates); - } + cp_error_at ("ambiguous template specialization `%D' for `%+D'", + template_id, decl); + chainon (candidates, templates); + print_candidates (candidates); return error_mark_node; } @@ -1445,8 +1423,7 @@ check_explicit_specialization (declarator, decl, template_count, flags) declaration. */ tmpl = determine_specialization (declarator, decl, &targs, - member_specialization, - 1); + member_specialization); if (!tmpl || tmpl == error_mark_node) /* We couldn't figure out what this declaration was @@ -4366,8 +4343,7 @@ tsubst_friend_function (decl, args) new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE); tmpl = determine_specialization (template_id, new_friend, &new_args, - /*need_member_template=*/0, - /*complain=*/1); + /*need_member_template=*/0); new_friend = instantiate_template (tmpl, new_args); goto done; } @@ -6045,8 +6021,8 @@ tsubst (t, args, complain, in_decl) Type deduction may fail for any of the following reasons: - Attempting to create an array with a size that is - zero or negative. */ + Attempting to create an array with a size that is + zero or negative. */ if (complain) cp_error ("creating array with size `%E'", max); @@ -6409,16 +6385,23 @@ tsubst (t, args, complain, in_decl) 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: + 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; }; + 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)) - { + 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)) { diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash30.C b/gcc/testsuite/g++.old-deja/g++.pt/crash30.C new file mode 100644 index 0000000..13dc37a --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash30.C @@ -0,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 - |