This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

c++ 2.96 patch lookup_template_class push_decl_namespace


Included below is a patch to the g++ 2.96 compiler that avoids an
error in the following test case:
----------<begin test case>---------------
// Build don't link
//Purpose:
//  Test nested template as template template arg.
//Result:
//  Before the patch, got:
//   `C' is not a template
template
  < template<typename S>class T
  >
  struct
A
  { T<int> m_t;
  };
  struct
B
  {
    template
      < typename V
      >
      struct
    C
      { V m_v;
      };
  };
  A
    <B
      ::C
    >
z
  ;
----------<end   test case>---------------
The reason the previous pt.c failed was because of the following
statements in function lookup_template_class:

            push_decl_namespace (context);
            template = lookup_name (d1, /*prefer_type=*/0);
            ...
            pop_decl_namespace ();

This failed because context was not a namespace in the above test
case.  The solution simply involves checking this condition and
calling lookup_field(context,d1,0,0) instead.
----------<ChangeLog>---------------
2000-06-26  Larry Evans  <jcampbell3@prodigy.net>

 * pt.c (lookup_template_class): dispatch on TREE_CODE(context)
 instead of assuming it's a NAMESPACE_DECL
----------<cvs diffs>---------------
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.446
diff -c -3 -p -r1.446 pt.c
*** pt.c 2000/06/23 06:49:44 1.446
--- pt.c 2000/06/25 12:16:24
*************** maybe_get_template_decl_from_type_decl (
*** 3713,3719 ****
     the class we are looking up.

     If the template class is really a local class in a template
!    function, then the FUNCTION_CONTEXT is the function in which it is
     being instantiated.  */

  tree
--- 3713,3719 ----
     the class we are looking up.

     If the template class is really a local class in a template
!    function, then the CONTEXT is the function in which it is
     being instantiated.  */

  tree
*************** lookup_template_class (d1, arglist, in_d
*** 3729,3765 ****
    if (TREE_CODE (d1) == IDENTIFIER_NODE)
      {
        if (IDENTIFIER_VALUE (d1)
!    && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))
   template = IDENTIFIER_VALUE (d1);
        else
!  {
!    if (context)
!      push_decl_namespace (context);
!    template = lookup_name (d1, /*prefer_type=*/0);
     template = maybe_get_template_decl_from_type_decl (template);
!    if (context)
!      pop_decl_namespace ();
!  }
        if (template)
   context = DECL_CONTEXT (template);
      }
    else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE
(d1)))
      {
        tree type = TREE_TYPE (d1);
!
        /* If we are declaring a constructor, say A<T>::A<T>, we will
get
!   an implicit typename for the second A.  Deal with it.  */
        if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
   type = TREE_TYPE (type);
!
        if (CLASSTYPE_TEMPLATE_INFO (type))
   {
!    template = CLASSTYPE_TI_TEMPLATE (type);
!    d1 = DECL_NAME (template);
   }
      }
    else if (TREE_CODE (d1) == ENUMERAL_TYPE
!     || (TYPE_P (d1) && IS_AGGR_TYPE (d1)))
      {
        template = TYPE_TI_TEMPLATE (d1);
        d1 = DECL_NAME (template);
--- 3729,3780 ----
    if (TREE_CODE (d1) == IDENTIFIER_NODE)
      {
        if (IDENTIFIER_VALUE (d1)
!       && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))
   template = IDENTIFIER_VALUE (d1);
        else
!   {
!         int is_namespace=0;
!         if (context)
!           {
!             is_namespace=TREE_CODE(context) == NAMESPACE_DECL;
!             if(is_namespace)
!               {
!                 push_decl_namespace(context);
!                 template = lookup_name (d1, /*prefer_type=*/0);
!               }
!             else
!               {
!                 template = lookup_field(context,d1,0,0);
!               }
!           }
!         else
!           {
!             template = lookup_name (d1, /*prefer_type=*/0);
!           }
     template = maybe_get_template_decl_from_type_decl (template);
!         if(is_namespace)
!             pop_decl_namespace ();
!       }
        if (template)
   context = DECL_CONTEXT (template);
      }
    else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE
(d1)))
      {
        tree type = TREE_TYPE (d1);
!
        /* If we are declaring a constructor, say A<T>::A<T>, we will
get
!     an implicit typename for the second A.  Deal with it.  */
        if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
   type = TREE_TYPE (type);
!
        if (CLASSTYPE_TEMPLATE_INFO (type))
   {
!      template = CLASSTYPE_TI_TEMPLATE (type);
!      d1 = DECL_NAME (template);
   }
      }
    else if (TREE_CODE (d1) == ENUMERAL_TYPE
!       || (TYPE_P (d1) && IS_AGGR_TYPE (d1)))
      {
        template = TYPE_TI_TEMPLATE (d1);
        d1 = DECL_NAME (template);

----------<g++ tests>---------------
runtest --tool g++
WARNING: Couldn't find the global config file.
Test Run By evansl on Sun Jun 25 12:33:28 2000
Native configuration is i586-pc-linux-gnu

  === g++ tests ===

Schedule of variations:
    unix

Running target unix
Using /usr/local/share/dejagnu/baseboards/unix.exp as board description
file for target.
Using /usr/local/share/dejagnu/config/unix.exp as generic interface file
for target.
Using
/home/evansl/prog_dev/gcc_all/gcc-2.96/snap/gcc/gcc/testsuite/config/default.exp
as tool-and-target-specific interface file.
Running
/home/evansl/prog_dev/gcc_all/gcc-2.96/snap/gcc/gcc/testsuite/g++.dg/special/ecos.exp
...
FAIL: g++.dg/special/conpr-1.C execution test
FAIL: g++.dg/special/conpr-2.C execution test
FAIL: g++.dg/special/conpr-3.C execution test
FAIL: g++.dg/special/conpr-3.C execution test
Running
/home/evansl/prog_dev/gcc_all/gcc-2.96/snap/gcc/gcc/testsuite/g++.old-deja/old-deja.exp
...
FAIL: g++.ext/initp1.C  Execution test
FAIL: g++.ext/instantiate1.C not instantiated (test for errors, line 18)

FAIL: g++.ext/instantiate1.C not instantiated (test for errors, line 20)

XPASS: g++.oliva/template7.C - conversion from int to non-scalar - (test
for bogus messages, line 12)
FAIL: g++.other/crash18.C (test for excess errors)
FAIL: g++.other/initstring.C (test for excess errors)
FAIL: g++.other/type.C caused compiler crash

  === g++ Summary ===

# of expected passes  5907
# of unexpected failures 10
# of unexpected successes 1
# of expected failures  98
# of untested testcases  8
/home/evansl/prog_dev/gcc_all/gcc-2.96/snap/objdir/gcc/testsuite/../g++
version 2.96 20000625 (experimental)




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]