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]
Other format: [Raw text]

Re: C++ PATCH: Empty classes, yet again




--On Monday, October 21, 2002 11:40:41 PM +0200 Krister Walfridsson <cato@df.lth.se> wrote:

On Mon, 21 Oct 2002, Mark Mitchell wrote:
> FWIW. This change introduces a regression for arm-unknown-netbsd1.5Y:
>
>    FAIL: g++.abi/vbase8-9.C  Execution test
>
> (the test dumps core with a segmentation fault when run.)

How disturbing.

During the construction of which object?  (Try removing lines
from the end of main until you no longer get an error.)
I can reproduce the problem with

   int main() {
      C9 c9;
   }

All the other constructors work (or they do at least not dump core... ;)
I believe this problem will be fixed by the attached patch, which corrects
yet another ABI bug involving empty classes.  Tested on i686-pc-linux-gnu,
applied on the mainline.

--
Mark Mitchell                mark@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com

2002-10-21  Mark Mitchell  <mark@codesourcery.com>

	* class.c (empty_base_at_nonzero_offset_p): New function.
	(layout_nonempty_base_or_field): Do not check for conflicts when
	laying out a virtual base using the GCC 3.2 ABI.
	(build_base_field): Correct checking for presence of empty classes
	at non-zero offsets when clearing CLASSTYPE_NEARLY_EMPTY_P.

2002-10-21  Mark Mitchell  <mark@codesourcery.com>

	* g++.dg/abi/vbase13.C: New test.
	* g++.dg/abi/vbase14.C: Likewise.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.482
diff -c -p -r1.482 class.c
*** cp/class.c	21 Oct 2002 21:47:44 -0000	1.482
--- cp/class.c	22 Oct 2002 05:01:02 -0000
*************** static bool type_requires_array_cookie P
*** 209,214 ****
--- 209,215 ----
 static bool contains_empty_class_p (tree);
 static tree dfs_base_derived_from (tree, void *);
 static bool base_derived_from (tree, tree);
+ static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);

 /* Macros for dfs walking during vtt construction. See
    dfs_ctor_vtable_bases_queue_p, dfs_build_secondary_vptr_vtt_inits
*************** layout_nonempty_base_or_field (record_la
*** 3674,3679 ****
--- 3675,3684 ----
 	 empty class, have nonzero size, any overlap can happen only
 	 with a direct or indirect base-class -- it can't happen with
 	 a data member.  */
+       /* G++ 3.2 did not check for overlaps when placing a non-empty
+ 	 virtual base.  */
+       if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo))
+ 	break;
       if (layout_conflict_p (type, offset, offsets, field_p))
 	{
 	  /* Strip off the size allocated to this field.  That puts us
*************** layout_nonempty_base_or_field (record_la
*** 3708,3713 ****
--- 3713,3728 ----
 			     t);
 }

+ /* Returns true if TYPE is empty and OFFSET is non-zero.  */
+
+ static int
+ empty_base_at_nonzero_offset_p (tree type,
+ 				tree offset,
+ 				splay_tree offsets ATTRIBUTE_UNUSED)
+ {
+   return is_empty_class (type) && !integer_zerop (offset);
+ }
+
 /* Layout the empty base BINFO.  EOC indicates the byte currently just
    past the end of the class, and should be correctly aligned for a
    class of the type indicated by BINFO; OFFSETS gives the offsets of
*************** build_base_field (record_layout_info rli
*** 3816,3829 ****
   else
     {
       tree eoc;

       /* On some platforms (ARM), even empty classes will not be
 	 byte-aligned.  */
       eoc = round_up (rli_size_unit_so_far (rli),
 		      CLASSTYPE_ALIGN_UNIT (basetype));
!       if (layout_empty_base (binfo, eoc, offsets, t))
! 	CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
!
       /* We do not create a FIELD_DECL for empty base classes because
 	 it might overlap some other field.  We want to be able to
 	 create CONSTRUCTORs for the class by iterating over the
--- 3831,3867 ----
   else
     {
       tree eoc;
+       bool atend;

       /* On some platforms (ARM), even empty classes will not be
 	 byte-aligned.  */
       eoc = round_up (rli_size_unit_so_far (rli),
 		      CLASSTYPE_ALIGN_UNIT (basetype));
!       atend = layout_empty_base (binfo, eoc, offsets, t);
!       /* A nearly-empty class "has no proper base class that is empty,
! 	 not morally virtual, and at an offset other than zero."  */
!       if (!TREE_VIA_VIRTUAL (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
! 	{
! 	  if (atend)
! 	    CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
! 	  /* The check above (used in G++ 3.2) is insufficient  because
! 	     an empty class placed at offset zero might itself have an
! 	     empty base at a non-zero offset.  */
! 	  else if (walk_subobject_offsets (basetype,
! 					   empty_base_at_nonzero_offset_p,
! 					   size_zero_node,
! 					   /*offsets=*/NULL,
! 					   /*max_offset=*/NULL_TREE,
! 					   /*vbases_p=*/true))
! 	    {
! 	      if (abi_version_at_least (2))
! 		CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
! 	      else if (warn_abi)
! 		warning ("class `%T' will be considered nearly empty in a "
! 			 "future version of GCC", t);
! 	    }
! 	}
! 	
       /* We do not create a FIELD_DECL for empty base classes because
 	 it might overlap some other field.  We want to be able to
 	 create CONSTRUCTORs for the class by iterating over the
Index: testsuite/g++.dg/abi/vbase13.C
===================================================================
RCS file: testsuite/g++.dg/abi/vbase13.C
diff -N testsuite/g++.dg/abi/vbase13.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/abi/vbase13.C	22 Oct 2002 05:01:02 -0000
***************
*** 0 ****
--- 1,17 ----
+ // { dg-do run }
+ // { dg-options "-fabi-version=0 -w" }
+
+ struct E1 {};
+ struct E2 : public E1 {};
+ struct E : public E1, public E2 {};
+ struct N : public E { virtual void f () {} };
+
+ struct X : virtual public N {
+ };
+
+ int main () {
+   X x;
+   /* N should not be the primary base of X; it is not nearly empty.  */
+   if ((void*)&x == (void*)(N*)&x)
+     return 1;
+ }
Index: testsuite/g++.dg/abi/vbase14.C
===================================================================
RCS file: testsuite/g++.dg/abi/vbase14.C
diff -N testsuite/g++.dg/abi/vbase14.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/abi/vbase14.C	22 Oct 2002 05:01:02 -0000
***************
*** 0 ****
--- 1,6 ----
+ // { dg-options "-Wabi" }
+
+ struct E1 {};
+ struct E2 : public E1 {}; // { dg-warning "layout" }
+ struct E : public E1, public E2 {}; // { dg-warning "layout|ambiguity" }
+ struct N : public E { virtual void f () {} };  // { dg-warning "nearly" }

Attachment: diffs
Description: Binary data


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