cp-tree.h (determine_specialization): Don't declare.
authorMark Mitchell <mark@markmitchell.com>
Tue, 2 Mar 1999 23:44:49 +0000 (23:44 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 2 Mar 1999 23:44:49 +0000 (23:44 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.pt/crash30.C [new file with mode: 0644]

index 3a7d3694c7166887cae69c5c44559a112ca4a060..e5098588e76346a36253535bcc778cde833a5265 100644 (file)
@@ -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.
index 59a067efeb74aeb91e4551cfce99c505cdfee0c5..935f8f9ff4aa41243011df35ab26befb639e4db0 100644 (file)
@@ -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));
index 0f6d228a92a99d490a70acc1355955f3cc2b91e8..a79b027d0f3262c2d6ba3bda3ff1d395925c8b4b 100644 (file)
@@ -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 (file)
index 0000000..13dc37a
--- /dev/null
@@ -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 -