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++ PATCH] Fix PR3391


Hi

The following patch fixes bug PR3391 where TYPE_BINFO of some tree nodes
are used for purposes other than information about base classes.  Those
are TYPENAME_TYPE (using TYPENAME_TYPE_FULLNAME as TYPE_BINFO) and 
BOUND_TEMPLATE_TEMPLATE_PARM (using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO).  
Since both nodes can appear as base class, such conflict uses of TYPE_BINFO 
should be mapped to other fields.  The proposed patch relocates:

- TYPENAME_TYPE_FULLNAME to TYPE_FIELDS
- TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO to template_info in lang_type

Bootstrapped and tested with no regressions.  OK to commit to the main
trunk?

--Kriang


2001-09-23  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

        * cp-tree.h (TYPE_BINFO): Update comment.
        (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): New macro.
        (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Use template_info.
        (TYPENAME_TYPE_FULLNAME): Use TYPE_FIELDS.
        (copy_type): Prototype new function.
        * lex.c (copy_lang_decl): Gather tree node statistics.
        (copy_lang_type): New function.
        (copy_type): Likewise.
        (cp_make_lang_type): Create lang_type for
        BOUND_TEMPLATE_TEMPLATE_PARM.  Set TYPE_BINFO for TYPENAME_TYPE
        and BOUND_TEMPLATE_TEMPLATE_PARM.
        * pt.c (tsubst): Use copy_type instead of copy_node.
        * search.c (lookup_field_1): Ignore TYPENAME_TYPE.

diff -cprN gcc-main-save2/gcc/cp/cp-tree.h gcc-main-new/gcc/cp/cp-tree.h
*** gcc-main-save2/gcc/cp/cp-tree.h     Sun Sep  9 16:26:39 2001
--- gcc-main-new/gcc/cp/cp-tree.h       Sat Sep 22 23:13:52 2001
*************** Boston, MA 02111-1307, USA.  */
*** 114,122 ****
  
     TYPE_BINFO
       For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO.
-      For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME.
-      For a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM,
-      this is TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
  
    BINFO_VIRTUALS
       For a binfo, this is a TREE_LIST.  The BV_DELTA of each node
--- 114,119 ----
*************** Boston, MA 02111-1307, USA.  */
*** 192,197 ****
--- 189,202 ----
                         __FUNCTION__);                         \
      __t; })
  
+ #define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE)         \
+ ({  const tree __t = NODE;                                    \
+     enum tree_code __c = TREE_CODE(__t);                      \
+     if (__c != BOUND_TEMPLATE_TEMPLATE_PARM)                  \
+       tree_check_failed (__t, BOUND_TEMPLATE_TEMPLATE_PARM,   \
+                        __FILE__, __LINE__, __FUNCTION__);     \
+     __t; })
+ 
  #else /* not ENABLE_TREE_CHECKING, or not gcc */
  
  #define VAR_OR_FUNCTION_DECL_CHECK(NODE)      NODE
*************** struct lang_decl
*** 2155,2162 ****
     non-type template parameters.  */
  #define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (ENUMERAL_TYPE_CHECK (NODE)))
  
! /* Template information for a bound template template parameter.  */
! #define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE))
  
  /* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
  #define TYPE_TEMPLATE_INFO(NODE)                      \
--- 2160,2169 ----
     non-type template parameters.  */
  #define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (ENUMERAL_TYPE_CHECK (NODE)))
  
! /* Template information for a template template parameter.  */
! #define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) \
!   (TYPE_LANG_SPECIFIC(BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \
!    ->template_info)
  
  /* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
  #define TYPE_TEMPLATE_INFO(NODE)                      \
*************** struct lang_decl
*** 2319,2325 ****
     this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the
     corresponding TYPE_DECL.  However, this may also be a
     TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'.  */
! #define TYPENAME_TYPE_FULLNAME(NODE) TYPE_BINFO (NODE)
  
  /* Nonzero if NODE is an implicit typename.  */
  #define IMPLICIT_TYPENAME_P(NODE) \
--- 2326,2332 ----
     this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the
     corresponding TYPE_DECL.  However, this may also be a
     TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'.  */
! #define TYPENAME_TYPE_FULLNAME(NODE) (TYPE_FIELDS (NODE))
  
  /* Nonzero if NODE is an implicit typename.  */
  #define IMPLICIT_TYPENAME_P(NODE) \
*************** extern tree identifier_typedecl_value           P
*** 3882,3887 ****
--- 3889,3895 ----
  extern tree build_lang_decl                   PARAMS ((enum tree_code, tree, tree));
  extern void retrofit_lang_decl                        PARAMS ((tree));
  extern tree copy_decl                           PARAMS ((tree));
+ extern tree copy_type                           PARAMS ((tree));
  extern tree cp_make_lang_type                 PARAMS ((enum tree_code));
  extern tree make_aggr_type                    PARAMS ((enum tree_code));
  extern void compiler_error                    PARAMS ((const char *, ...))
diff -cprN gcc-main-save2/gcc/cp/lex.c gcc-main-new/gcc/cp/lex.c
*** gcc-main-save2/gcc/cp/lex.c Fri Sep 21 21:34:41 2001
--- gcc-main-new/gcc/cp/lex.c   Sat Sep 22 23:13:53 2001
*************** copy_lang_decl (node)
*** 1562,1567 ****
--- 1562,1572 ----
    ld = (struct lang_decl *) ggc_alloc (size);
    memcpy (ld, DECL_LANG_SPECIFIC (node), size);
    DECL_LANG_SPECIFIC (node) = ld;
+ 
+ #ifdef GATHER_STATISTICS
+   tree_node_counts[(int)lang_decl] += 1;
+   tree_node_sizes[(int)lang_decl] += size;
+ #endif
  }
  
  /* Copy DECL, including any language-specific parts.  */
*************** copy_decl (decl)
*** 1577,1590 ****
    return copy;
  }
  
  tree
  cp_make_lang_type (code)
       enum tree_code code;
  {
    register tree t = make_node (code);
  
!   /* Set up some flags that give proper default behavior.  */
!   if (IS_AGGR_TYPE_CODE (code))
      {
        struct lang_type *pi;
  
--- 1582,1632 ----
    return copy;
  }
  
+ /* Replace the shared language-specific parts of NODE with a new copy.  */
+ 
+ void
+ copy_lang_type (node)
+      tree node;
+ {
+   int size;
+   struct lang_type *lt;
+ 
+   if (! TYPE_LANG_SPECIFIC (node))
+     return;
+ 
+   size = sizeof (struct lang_type);
+   lt = (struct lang_type *) ggc_alloc (size);
+   memcpy (lt, TYPE_LANG_SPECIFIC (node), size);
+   TYPE_LANG_SPECIFIC (node) = lt;
+ 
+ #ifdef GATHER_STATISTICS
+   tree_node_counts[(int)lang_type] += 1;
+   tree_node_sizes[(int)lang_type] += size;
+ #endif
+ }
+ 
+ /* Copy TYPE, including any language-specific parts.  */
+ 
+ tree
+ copy_type (type)
+      tree type;
+ {
+   tree copy;
+ 
+   copy = copy_node (type);
+   copy_lang_type (copy);
+   return copy;
+ }
+ 
  tree
  cp_make_lang_type (code)
       enum tree_code code;
  {
    register tree t = make_node (code);
  
!   /* Create lang_type structure.  */
!   if (IS_AGGR_TYPE_CODE (code)
!       || code == BOUND_TEMPLATE_TEMPLATE_PARM)
      {
        struct lang_type *pi;
  
*************** cp_make_lang_type (code)
*** 1592,1597 ****
--- 1634,1649 ----
            ggc_alloc_cleared (sizeof (struct lang_type)));
  
        TYPE_LANG_SPECIFIC (t) = pi;
+ 
+ #ifdef GATHER_STATISTICS
+       tree_node_counts[(int)lang_type] += 1;
+       tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
+ #endif
+     }
+ 
+   /* Set up some flags that give proper default behavior.  */
+   if (IS_AGGR_TYPE_CODE (code))
+     {
        SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
        CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
  
*************** cp_make_lang_type (code)
*** 1599,1609 ****
         presence of parse errors, the normal was of assuring this
         might not ever get executed, so we lay it out *immediately*.  */
        build_pointer_type (t);
- 
- #ifdef GATHER_STATISTICS
-       tree_node_counts[(int)lang_type] += 1;
-       tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
- #endif
      }
    else
      /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits.  But,
--- 1651,1656 ----
*************** cp_make_lang_type (code)
*** 1615,1621 ****
       since they can be virtual base types, and we then need a
       canonical binfo for them.  Ideally, this would be done lazily for
       all types.  */
!   if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM)
      TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE);
  
    return t;
--- 1662,1670 ----
       since they can be virtual base types, and we then need a
       canonical binfo for them.  Ideally, this would be done lazily for
       all types.  */
!   if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM
!       || code == BOUND_TEMPLATE_TEMPLATE_PARM
!       || code == TYPENAME_TYPE)
      TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE);
  
    return t;
diff -cprN gcc-main-save2/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save2/gcc/cp/pt.c  Fri Sep 21 21:34:41 2001
--- gcc-main-new/gcc/cp/pt.c    Sat Sep 22 22:46:23 2001
*************** tsubst (t, args, complain, in_decl)
*** 6435,6441 ****
              }
            else
              {
!               r = copy_node (t);
                TEMPLATE_TYPE_PARM_INDEX (r)
                  = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
                                                r, levels);
--- 6435,6441 ----
              }
            else
              {
!               r = copy_type (t);
                TEMPLATE_TYPE_PARM_INDEX (r)
                  = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
                                                r, levels);
diff -cprN gcc-main-save2/gcc/cp/search.c gcc-main-new/gcc/cp/search.c
*** gcc-main-save2/gcc/cp/search.c      Fri Sep 21 21:34:41 2001
--- gcc-main-new/gcc/cp/search.c        Sat Sep 22 23:14:59 2001
*************** lookup_field_1 (type, name)
*** 564,574 ****
    register tree field;
  
    if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
!       || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
!     /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM are not fields at all;
         instead TYPE_FIELDS is the TEMPLATE_PARM_INDEX.  (Miraculously,
         the code often worked even when we treated the index as a list
!        of fields!)  */
      return NULL_TREE;
  
    if (TYPE_NAME (type)
--- 564,577 ----
    register tree field;
  
    if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
!       || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
!       || TREE_CODE (type) == TYPENAME_TYPE)
!     /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM and 
!        BOUND_TEMPLATE_TEMPLATE_PARM are not fields at all;
         instead TYPE_FIELDS is the TEMPLATE_PARM_INDEX.  (Miraculously,
         the code often worked even when we treated the index as a list
!        of fields!)
!        The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME.  */
      return NULL_TREE;
  
    if (TYPE_NAME (type)
diff -cprN gcc-main-save2/gcc/testsuite/g++.dg/template/ttp1.C gcc-main-new/gcc/testsuite/g++.dg/template/ttp1.C
*** gcc-main-save2/gcc/testsuite/g++.dg/template/ttp1.C Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/ttp1.C   Sat Sep 22 20:47:36 2001
***************
*** 0 ****
--- 1,9 ----
+ // Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+ // { dg-do compile }
+ 
+ template <template <typename T> class A >
+ class B : virtual A<void>
+ {
+       typedef int INT;
+       INT i;
+ };
diff -cprN gcc-main-save2/gcc/testsuite/g++.dg/template/typename1.C gcc-main-new/gcc/testsuite/g++.dg/template/typename1.C
*** gcc-main-save2/gcc/testsuite/g++.dg/template/typename1.C    Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/typename1.C      Sat Sep 22 20:47:45 2001
***************
*** 0 ****
--- 1,9 ----
+ // Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+ // { dg-do compile }
+ 
+ template <class T>
+ class B : virtual T::A
+ {
+       typedef int INT;
+       INT i;
+ };


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