From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26254 invoked by alias); 9 Oct 2014 07:58:45 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 26209 invoked by uid 48); 9 Oct 2014 07:58:41 -0000 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/63495] struct __attribute__ ((aligned (8))) broken on x86 Date: Thu, 09 Oct 2014 07:58:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Version: 4.9.1 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_status cf_reconfirmed_on cc everconfirmed Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-10/txt/msg00645.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63495 Jakub Jelinek changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2014-10-09 CC| |jakub at gcc dot gnu.org, | |jsm28 at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Jakub Jelinek --- This started with r205685. The problem is in the x86 32-bit ABI, which decreases alignment of fields to 32 bits if the field has integral mode, or DFmode/DCmode or complex integral mode. int x86_field_alignment (tree field, int computed) { enum machine_mode mode; tree type = TREE_TYPE (field); if (TARGET_64BIT || TARGET_ALIGN_DOUBLE) return computed; mode = TYPE_MODE (strip_array_types (type)); if (mode == DFmode || mode == DCmode || GET_MODE_CLASS (mode) == MODE_INT || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) return MIN (32, computed); return computed; } When the struct has only a single field, it is QImode, therefore despite the user forced alignment the alignment is lowered to 32 bits. Now, when actually laying out struct s fields, such as: struct T { char a; struct s s; } t = { 1, { 2 } }; it actually is given 64-bit alignment, because ADJUST_FIELD_ALIGN is not used in that case: if (! packed_p && ! DECL_USER_ALIGN (decl)) { /* Some targets (i.e. i386, VMS) limit struct field alignment to a lower boundary than alignment of variables unless it was overridden by attribute aligned. */ #ifdef BIGGEST_FIELD_ALIGNMENT DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), (unsigned) BIGGEST_FIELD_ALIGNMENT); #endif #ifdef ADJUST_FIELD_ALIGN DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl)); #endif } As do_type_align for FIELD_DECLs sets DECL_USER_ALIGN: static inline void do_type_align (tree type, tree decl) { if (TYPE_ALIGN (type) > DECL_ALIGN (decl)) { DECL_ALIGN (decl) = TYPE_ALIGN (type); if (TREE_CODE (decl) == FIELD_DECL) DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type); } } if TYPE_USER_ALIGN is set, IMHO ADJUST_FIELD_ALIGN and corresponding BIGGEST_FIELD_ALIGNMENT will never be used.