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]

C++ PATCH to layout_empty_base for c++/10179


For non-empty bases, the base field we create provides the necessary alignment. But we don't create a field for empty bases, so we need to propagate alignment requirements explicitly. I'm a bit surprised that people want to use empty bases to impose alignment requirements, but it seems like it ought to work if they do.

Tested x86_64-pc-linux-gnu, applied to trunk.

2007-09-28  Jason Merrill  <jason@redhat.com>

	PR c++/10179
	* class.c (layout_empty_base): Take rli parameter, update
	rli->record_align if empty base has user-specified alignment.
	(build_base_field): Pass rli to it.

Index: cp/class.c
===================================================================
*** cp/class.c	(revision 128868)
--- cp/class.c	(working copy)
*************** static void initialize_vtable (tree, tre
*** 179,185 ****
  static void layout_nonempty_base_or_field (record_layout_info,
  					   tree, tree, splay_tree);
  static tree end_of_class (tree, int);
! static bool layout_empty_base (tree, tree, splay_tree);
  static void accumulate_vtbl_inits (tree, tree, tree, tree, tree);
  static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree,
  					       tree);
--- 179,185 ----
  static void layout_nonempty_base_or_field (record_layout_info,
  					   tree, tree, splay_tree);
  static tree end_of_class (tree, int);
! static bool layout_empty_base (record_layout_info, tree, tree, splay_tree);
  static void accumulate_vtbl_inits (tree, tree, tree, tree, tree);
  static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree,
  					       tree);
*************** empty_base_at_nonzero_offset_p (tree typ
*** 3517,3523 ****
     type.  Return nonzero iff we added it at the end.  */
  
  static bool
! layout_empty_base (tree binfo, tree eoc, splay_tree offsets)
  {
    tree alignment;
    tree basetype = BINFO_TYPE (binfo);
--- 3517,3524 ----
     type.  Return nonzero iff we added it at the end.  */
  
  static bool
! layout_empty_base (record_layout_info rli, tree binfo,
! 		   tree eoc, splay_tree offsets)
  {
    tree alignment;
    tree basetype = BINFO_TYPE (binfo);
*************** layout_empty_base (tree binfo, tree eoc,
*** 3563,3568 ****
--- 3564,3578 ----
  	  propagate_binfo_offsets (binfo, alignment);
  	}
      }
+ 
+   if (CLASSTYPE_USER_ALIGN (basetype))
+     {
+       rli->record_align = MAX (rli->record_align, CLASSTYPE_ALIGN (basetype));
+       if (warn_packed)
+ 	rli->unpacked_align = MAX (rli->unpacked_align, CLASSTYPE_ALIGN (basetype));
+       TYPE_USER_ALIGN (rli->t) = 1;
+     }
+ 
    return atend;
  }
  
*************** build_base_field (record_layout_info rli
*** 3626,3632 ****
  	 byte-aligned.  */
        eoc = round_up (rli_size_unit_so_far (rli),
  		      CLASSTYPE_ALIGN_UNIT (basetype));
!       atend = layout_empty_base (binfo, eoc, offsets);
        /* A nearly-empty class "has no proper base class that is empty,
  	 not morally virtual, and at an offset other than zero."  */
        if (!BINFO_VIRTUAL_P (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
--- 3636,3642 ----
  	 byte-aligned.  */
        eoc = round_up (rli_size_unit_so_far (rli),
  		      CLASSTYPE_ALIGN_UNIT (basetype));
!       atend = layout_empty_base (rli, binfo, eoc, offsets);
        /* A nearly-empty class "has no proper base class that is empty,
  	 not morally virtual, and at an offset other than zero."  */
        if (!BINFO_VIRTUAL_P (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
Index: testsuite/g++.dg/ext/align2.C
===================================================================
*** testsuite/g++.dg/ext/align2.C	(revision 0)
--- testsuite/g++.dg/ext/align2.C	(revision 0)
***************
*** 0 ****
--- 1,14 ----
+ // PR c++/10179
+ 
+ struct __attribute((aligned(__alignof(double)))) A
+ { /* empty */ };
+ 
+ struct T : public A
+ {
+   char c;
+ };
+ 
+ template<bool> struct StaticAssert;
+ template<> struct StaticAssert<true> {};
+ 
+ StaticAssert<__alignof(T) == __alignof(double)> d;

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