From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18801 invoked by alias); 20 Jan 2006 16:36:49 -0000 Received: (qmail 18764 invoked by uid 48); 20 Jan 2006 16:36:44 -0000 Date: Fri, 20 Jan 2006 16:36:00 -0000 Message-ID: <20060120163644.18763.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug middle-end/22275] [3.4/4.0/4.1/4.2 Regression] bitfield layout change (regression?) In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "matz at suse dot de" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2006-01/txt/msg02085.txt.bz2 List-Id: ------- Comment #37 from matz at suse dot de 2006-01-20 16:36 ------- Hmpf. One more difficulty. x86 uses the ADJUST_FIELD_ALIGN macro to further fiddle with alignments of fields. On x86 this is used to adjust the alignment of long long to 4 (instead of the natural 8). This is used only when the field is not DECL_PACKED (makes sense). This has the funny side-effect that a struct containing a long long zero-width bitfield aligns to 4 for unpacked and to 8 for packed structs, i.e. the packed struct actually is _larger_ than the unpacked struct. E.g. the running example with UINT being long long: typedef int BOOL; typedef unsigned long long UINT; #pragma pack(1) typedef struct { BOOL fFullPathTitle:1; BOOL fSaveLocalView:1; BOOL fNotShell:1; BOOL fSimpleDefault:1; BOOL fDontShowDescBar:1; BOOL fNewWindowMode:1; BOOL fShowCompColor:1; BOOL fDontPrettyNames:1; BOOL fAdminsCreateCommonGroups:1; UINT fUnusedFlags:7; UINT :0; UINT fMenuEnumFilter; } CABINETSTATE; This struct being unpacked (only influenced by #pragma) has size 12 after my patch on i686, and size 16 (!) when being packed via attribute. What's even more ugly is that pre-3.4 GCC had a size of 16 for both cases (pragma or attribute packed) on i686 :-( So, how would we like to handle this? Doing as pre 3.4 did is probably possible but not trivially done. Basically the code doing this is: if (! DECL_USER_ALIGN (decl) && ! DECL_PACKED (decl)) { #ifdef ADJUST_FIELD_ALIGN DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl)); #endif } Now, I could just ignore DECL_PACKED for zero-width bitfields, then the adjustment would be done for both cases and we had a size of 12 with attribute or pragma, i.e. not the same as pre 3.4 in both. I also could never adjust zero-width bitfields, so that they would get their natural alignment even when the target wanted something else. Then both cases would have size 16, being the same as pre 3.4. I'm leaning towards not doing field adjustments for zero-width bitfields at all, having the effect that a zero-width bitfield has a user-alignment set explicitely (of it's base type). I think if one understands zero-width bitfields purely as alignment constraints than this implicit DECL_USER_ALIGN behaviour seems sensible. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22275