diff mbox

Fix up _Alignof with user aligned types (PR c/63495)

Message ID 20141010104615.GG10376@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Oct. 10, 2014, 10:46 a.m. UTC
Hi!

As the testcase shows, _Alignof can sometimes return smaller number
than the minimum alignment.  That is because when laying out structures,
fields with types with TYPE_USER_ALIGN set have also DECL_USER_ALIGN
set and therefore neither BIGGEST_FIELD_ALIGNMENT nor ADJUST_FIELD_ALIGN
is applied to them, but min_align_of_type was applying that unconditionally.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk/4.9?

2014-10-10  Jakub Jelinek  <jakub@redhat.com>

	PR c/63495
	* stor-layout.c (min_align_of_type): Don't decrease alignment
	through BIGGEST_FIELD_ALIGNMENT or ADJUST_FIELD_ALIGN if
	TYPE_USER_ALIGN is set.

	* gcc.target/i386/pr63495.c: New test.


	Jakub

Comments

Joseph Myers Oct. 10, 2014, 4:02 p.m. UTC | #1
On Fri, 10 Oct 2014, Jakub Jelinek wrote:

> Hi!
> 
> As the testcase shows, _Alignof can sometimes return smaller number
> than the minimum alignment.  That is because when laying out structures,
> fields with types with TYPE_USER_ALIGN set have also DECL_USER_ALIGN
> set and therefore neither BIGGEST_FIELD_ALIGNMENT nor ADJUST_FIELD_ALIGN
> is applied to them, but min_align_of_type was applying that unconditionally.
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk/4.9?
> 
> 2014-10-10  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c/63495
> 	* stor-layout.c (min_align_of_type): Don't decrease alignment
> 	through BIGGEST_FIELD_ALIGNMENT or ADJUST_FIELD_ALIGN if
> 	TYPE_USER_ALIGN is set.
> 
> 	* gcc.target/i386/pr63495.c: New test.

OK.
diff mbox

Patch

--- gcc/stor-layout.c.jj	2014-09-01 09:43:56.000000000 +0200
+++ gcc/stor-layout.c	2014-10-09 09:56:49.760893630 +0200
@@ -2400,17 +2400,19 @@  min_align_of_type (tree type)
 {
   unsigned int align = TYPE_ALIGN (type);
   align = MIN (align, BIGGEST_ALIGNMENT);
+  if (!TYPE_USER_ALIGN (type))
+    {
 #ifdef BIGGEST_FIELD_ALIGNMENT
-  align = MIN (align, BIGGEST_FIELD_ALIGNMENT);
+      align = MIN (align, BIGGEST_FIELD_ALIGNMENT);
 #endif
-  unsigned int field_align = align;
+      unsigned int field_align = align;
 #ifdef ADJUST_FIELD_ALIGN
-  tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
-			   type);
-  field_align = ADJUST_FIELD_ALIGN (field, field_align);
-  ggc_free (field);
+      tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, type);
+      field_align = ADJUST_FIELD_ALIGN (field, field_align);
+      ggc_free (field);
 #endif
-  align = MIN (align, field_align);
+      align = MIN (align, field_align);
+    }
   return align / BITS_PER_UNIT;
 }
 
--- gcc/testsuite/gcc.target/i386/pr63495.c.jj	2014-10-09 09:59:46.036634365 +0200
+++ gcc/testsuite/gcc.target/i386/pr63495.c	2014-10-09 10:01:09.231096165 +0200
@@ -0,0 +1,6 @@ 
+/* PR c/63495 */
+/* { dg-do compile { target { i?86-*-linux* x86_64-*-linux* } } } */
+/* { dg-options "-std=gnu11" } */
+
+struct __attribute__ ((aligned (8))) S { char c; };
+_Static_assert (_Alignof (struct S) >= 8, "wrong alignment");