This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to layout_empty_base for c++/10179
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 28 Sep 2007 14:06:34 -0400
- Subject: 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;