Bug 22491

Summary: template bug in gcc 2.96
Product: [Retired] Red Hat Linux Reporter: Vaibhav A Nalawade <vaibhav>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: David Lawrence <dkl>
Severity: high Docs Contact:
Priority: high    
Version: 7.0CC: vaibhav
Target Milestone: ---   
Target Release: ---   
Hardware: i686   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2000-12-19 10:42:04 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Vaibhav A Nalawade 2000-12-19 10:42:01 UTC
Hi all,

	This is the first time I am using bugzilla for reporting a bug so
if I have missed some information please bring it to my
notice(vaibhav).

	The following code if compiled with gcc 2.96 gives error .

code:

#include <stdio.h>
#include <stdlib.h>

class Dummy {

 int i;
};

template < class X >
class Array {
int i;
public :
static void * operator new(size_t);
};
void * Array<Dummy>::operator new(size_t i) {
printf ("\n new of Dummy ");
return (void *)malloc(i);
}

template <class X> void * Array<class X>::operator new(size_t i)
{
printf ("\n new of X");
return (void *)malloc(i);
}

Array<Dummy> *a;
Array<int> *i;

int main() {

a = new Array<Dummy>;
i = new Array<int>;

return 0;
}

error:
compiler-patch-test.cxx:25: using template type parameter `X' after 
`class'

There is a patch with me for the same bug on egcs 2.91.66 .But I cannot
find similar patch for gcc 2.96 . Morever this patch cannot be
applied to gcc 2.96 as it gives hunk fail error and the patch does not get
applied. Can you suggest as to how should I convert this egcs patch
so that it can be applied on gcc 2.96 compiler source code or do you
have any patch that solves this problem.? 

thanks 
Vaibhav Nalawade
Software Engineer 
Versant India Pvt Ltd
Subsidiary of :
Versant Corporation 
Fremont USA.

The patch is :egcs-1.1.x-objy.patch

Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.162.2.7
diff -c -p -r1.162.2.7 pt.c
*** pt.c        1998/10/28 20:36:04     1.162.2.7
--- pt.c        1999/02/23 07:29:48
*************** determine_specialization (template_id, d
*** 788,794 ****
--- 788,796 ----
       int complain;
  {
    tree fns, targs_in;
+   tree targs;
    tree templates = NULL_TREE;
+   tree candidates = NULL_TREE;
    tree fn;
    int i;

*************** determine_specialization (template_id, d
*** 812,840 ****
        tree tmpl;

        fn = OVL_CURRENT (fns);
!       if (!need_member_template
!         && TREE_CODE (fn) == FUNCTION_DECL
!         && DECL_FUNCTION_MEMBER_P (fn)
!         && DECL_USE_TEMPLATE (fn)
!         && DECL_TI_TEMPLATE (fn))
!       /* We can get here when processing something like:
!            template <class T> class X { void f(); }
!            template <> void X<int>::f() {}
!          We're specializing a member function, but not a member
!          template.  */
!       tmpl = DECL_TI_TEMPLATE (fn);
!       else if (TREE_CODE (fn) != TEMPLATE_DECL
!              || (need_member_template && !is_member_template (fn)))
        continue;
        else
!       tmpl = fn;

!       if (list_length (targs_in) > DECL_NTPARMS (tmpl))
!       continue;

        if (decl == NULL_TREE)
        {
!         tree targs = make_scratch_vec (DECL_NTPARMS (tmpl));

          /* We allow incomplete unification here, because we are going to
             check all the functions. */
--- 814,875----
        tree tmpl;

        fn = OVL_CURRENT (fns);
!
!       if (TREE_CODE (fn) == TEMPLATE_DECL)
!       /* DECL might be a specialization of FN.  */
!       tmpl = fn;
!       else if (need_member_template)
!       /* FN is an ordinary member function, and we need a
!          specialization of a member template.  */
!       continue;
!       else if (TREE_CODE (fn) != FUNCTION_DECL)
!       /* We can get IDENTIFIER_NODEs here in certain erroneous
!          cases.  */
!       continue;
!       else if (!DECL_FUNCTION_MEMBER_P (fn))
!       /* 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;

!         /* This is an ordinary member function.  However, since
!            we're here, we can assume it's enclosing class is a
!            template class.  For example,
!
!              template <typename T> struct S { void f(); };
!              template <> void S<int>::f() {}
!
!            Here, S<int>::f is a non-template, but S<int> is a
!            template class.  If FN has the same type as DECL, we
!            might be in business.  */
!         if (!comptypes (TREE_TYPE (TREE_TYPE (decl)),
!                         TREE_TYPE (TREE_TYPE (fn)), 1))
!           /* The return types differ.  */
!           continue;
!
!         /* Adjust the type of DECL in case FN is a static member.  */
!         decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
!         if (DECL_STATIC_FUNCTION_P (fn)
!             && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
!           decl_arg_types = TREE_CHAIN (decl_arg_types);
!
!         if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
!                        decl_arg_types, 1))
!           /* They match!  */
!           candidates = tree_cons (NULL_TREE, fn, candidates);
!
!         continue;
!       }

        if (decl == NULL_TREE)
        {
!         targs = make_scratch_vec (DECL_NTPARMS (tmpl));

          /* We allow incomplete unification here, because we are going to
             check all the functions. */
*************** determine_specialization (template_id, d
*** 848,872 ****
          if (i == 0)
            /* Unification was successful.  */
            templates = scratch_tree_cons (targs, tmpl, templates);
        }
        else
!       templates = scratch_tree_cons (NULL_TREE, tmpl, templates);
      }

    if (decl != NULL_TREE)
      {
        tree tmpl = most_specialized (templates, decl, targs_in);
-
-       if (tmpl == error_mark_node)
-       goto ambiguous;
-       else if (tmpl == NULL_TREE)
-       goto no_match;

!       *targs_out = get_bindings (tmpl, decl, targs_in);
!       return tmpl;
      }

!   if (templates == NULL_TREE)
      {
      no_match:
        if (complain)
--- 883,917 ----
          if (i == 0)
            /* Unification was successful.  */
            templates = scratch_tree_cons (targs, tmpl, templates);
+
+         continue;
        }
        else
!       /* See whether this function might be a specialization of this
!          template.  */
!       targs = get_bindings (tmpl, decl, targs_in);
!
!       if (!targs)
!       /* We cannot deduce template arguments that when used to
!          specialize TMPL will produce DECL.  */
!       continue;
!
!       /* Save this template, and the arguments deduced.  */
!       templates = scratch_tree_cons (targs, tmpl, templates);
      }

    if (decl != NULL_TREE)
      {
        tree tmpl = most_specialized (templates, decl, targs_in);

!       if (tmpl && tmpl != error_mark_node)
!       {
!         targs = get_bindings (tmpl, decl, targs_in);
!         templates = scratch_tree_cons (targs, tmpl, NULL_TREE);
!       }
      }

!   if (templates == NULL_TREE && candidates == NULL_TREE)
      {
      no_match:
        if (complain)
*************** determine_specialization (template_id, d
*** 877,883 ****
        }
        return NULL_TREE;
      }
!   else if (TREE_CHAIN (templates) != NULL_TREE)
      {
      ambiguous:
        if (complain)
--- 922,930 ----
        }
        return NULL_TREE;
      }
!   else if ((templates && TREE_CHAIN (templates))
!          || (candidates && TREE_CHAIN (candidates))
!          || (templates && candidates))
      {
      ambiguous:
        if (complain)
*************** determine_specialization (template_id, d
*** 891,896 ****
--- 938,952 ----
      }

    /* We have one, and exactly one, match. */
+   if (candidates)
+     {
+       /* It was a specialization of an ordinary member function in a
+        template class.  */
+       *targs_out = copy_node (DECL_TI_ARGS (TREE_VALUE (candidates)));
+       return DECL_TI_TEMPLATE (TREE_VALUE (candidates));
+     }
+
+   /* It was a specialization of a template.  */
    *targs_out = TREE_PURPOSE (templates);
    return TREE_VALUE (templates);
  }

Comment 1 Jakub Jelinek 2000-12-19 11:01:48 UTC
That code is not valid ISO C++, that's why it is rejected.
You should write:
template <class X> void * Array<X>::operator new(size_t i)