[C++ PATCH for 3.1] Fix PR6716 regression (take 2)

Kriang Lerdsuwanakij lerdsuwa@users.sourceforge.net
Sun Jun 23 02:17:00 GMT 2002


Hi

This patch is my second attempt at fixing PR6716, an ICE on
illegal code containing incomplete class which is a regression
from GCC 3.0.  The failure (testcase included in the patch below)
is caused by layout_class_type of nesting of classes Z<int>, 
Y<Z<int> >, and X<Z<int> >.  Incomplete types end up with 
TYPE_SIZE being size_zero_node and are indistinguishable from
ordinary empty classes.  Tree node traverse functions fail to
notice this and endlessly loop through the fields.

In this patch, incomplete classes are now handled inside
layout_class_type.  The best solution I found is breaking the
endless loop of tree structure by removing the incomplete fields.
So that the rest of compiler can handle without introducing
any extra lang-specific flags and special logic walk_* functions.

Bootstrapped and tested with no regressions.  Ok to commit to 3.1 branch
and main trunk?

--Kriang

2002-06-23  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

        PR c++/6716
        * class.c (layout_class_type): Remove fields that are incomplete.

2002-06-23  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

        * g++.dg/template/instantiate1.C: New test.

diff -cprN gcc-31-save/gcc/cp/class.c gcc-31-new/gcc/cp/class.c
*** gcc-31-save/gcc/cp/class.c  Sun May 19 17:07:23 2002
--- gcc-31-new/gcc/cp/class.c   Sun Jun 23 00:39:30 2002
*************** layout_class_type (t, empty_p, vfuns_p, 
*** 4819,4826 ****
       tree *new_virtuals_p;
       tree *overridden_virtuals_p;
  {
!   tree non_static_data_members;
!   tree field;
    tree vptr;
    record_layout_info rli;
    unsigned HOST_WIDE_INT eoc;
--- 4819,4826 ----
       tree *new_virtuals_p;
       tree *overridden_virtuals_p;
  {
!   tree *non_static_data_members;
!   tree *field_ptr;
    tree vptr;
    record_layout_info rli;
    unsigned HOST_WIDE_INT eoc;
*************** layout_class_type (t, empty_p, vfuns_p, 
*** 4829,4835 ****
    splay_tree empty_base_offsets;
  
    /* Keep track of the first non-static data member.  */
!   non_static_data_members = TYPE_FIELDS (t);
  
    /* Start laying out the record.  */
    rli = start_record_layout (t);
--- 4829,4835 ----
    splay_tree empty_base_offsets;
  
    /* Keep track of the first non-static data member.  */
!   non_static_data_members = &TYPE_FIELDS (t);
  
    /* Start laying out the record.  */
    rli = start_record_layout (t);
*************** layout_class_type (t, empty_p, vfuns_p, 
*** 4846,4851 ****
--- 4846,4852 ----
    if (vptr)
      {
        TYPE_FIELDS (t) = chainon (vptr, TYPE_FIELDS (t));
+       non_static_data_members = &TREE_CHAIN (*non_static_data_members);
        place_field (rli, vptr);
      }
  
*************** layout_class_type (t, empty_p, vfuns_p, 
*** 4856,4865 ****
      CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
    
    /* Layout the non-static data members.  */
!   for (field = non_static_data_members; field; field = TREE_CHAIN (field))
      {
        tree type;
        tree padding;
  
        /* We still pass things that aren't non-static data members to
         the back-end, in case it wants to do something with them.  */
--- 4857,4867 ----
      CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
    
    /* Layout the non-static data members.  */
!   for (field_ptr = non_static_data_members; *field_ptr; )
      {
        tree type;
        tree padding;
+       tree field = *field_ptr;
  
        /* We still pass things that aren't non-static data members to
         the back-end, in case it wants to do something with them.  */
*************** layout_class_type (t, empty_p, vfuns_p, 
*** 4878,4888 ****
--- 4880,4900 ----
             S1 is still incomplete.)  */
          if (TREE_CODE (field) == VAR_DECL)
            maybe_register_incomplete_var (field);
+ 
+         field_ptr = &TREE_CHAIN (field);
          continue;
        }
  
        type = TREE_TYPE (field);
  
+       /* Field with incomplete type can arise from illegal code.
+        They are removed from the list of fields here.  */
+       if (!COMPLETE_TYPE_P (type))
+       {
+         *field_ptr = TREE_CHAIN (field);
+         continue;
+       }
+ 
        /* If this field is a bit-field whose width is greater than its
         type, then there are some special rules for allocating
         it.  */
*************** layout_class_type (t, empty_p, vfuns_p, 
*** 4934,4939 ****
--- 4946,4953 ----
                                         NULL_TREE, 
                                         empty_base_offsets, t);
        }
+ 
+       field_ptr = &TREE_CHAIN (field);
      }
  
    /* It might be the case that we grew the class to allocate a
diff -cprN gcc-31-save/gcc/testsuite/g++.dg/template/instantiate1.C gcc-31-new/gcc/testsuite/g++.dg/template/instantiate1.C
*** gcc-31-save/gcc/testsuite/g++.dg/template/instantiate1.C    Thu Jan  1 07:00:00 1970
--- gcc-31-new/gcc/testsuite/g++.dg/template/instantiate1.C     Sun Jun 23 00:56:54 2002
***************
*** 0 ****
--- 1,21 ----
+ // { dg-do compile }
+ // Origin:
+ 
+ // PR c++/6716
+ // ICE in complex class structure when components are incomplete
+ 
+ template <class T> struct X { // { dg-error "type|declaration" }
+   T t;
+ };
+ 
+ template <class T> struct Y { // { dg-error "instantiated|declaration" }
+   X<T> x;
+ };
+ 
+ template <class T> struct Z { // { dg-error "instantiated|declaration" }
+   Y<Z<T> > y;
+ };
+ 
+ struct ZZ : Z<int>
+ {                             // { dg-error "instantiated" }
+ };



More information about the Gcc-patches mailing list