re PR c/61053 (_Alignas(long long) reduces alignment of long long)
authorMarek Polacek <polacek@redhat.com>
Thu, 8 May 2014 18:19:09 +0000 (18:19 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 8 May 2014 18:19:09 +0000 (18:19 +0000)
PR c/61053
c-family/
* c-common.c (min_align_of_type): New function factored out from...
(c_sizeof_or_alignof_type): ...here.
* c-common.h (min_align_of_type): Declare.
c/
* c-decl.c (grokdeclarator): Use min_align_of_type instead of
TYPE_ALIGN_UNIT.
testsuite/
* gcc.dg/pr61053.c: New test.

From-SVN: r210230

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr61053.c [new file with mode: 0644]

index 06a1b1468beddba0083e6f4fb0c2438b0301408e..fc84f31e4821155378194699d3f7e2dc21e025fd 100644 (file)
@@ -1,3 +1,10 @@
+2014-05-08  Marek Polacek  <polacek@redhat.com>
+
+       PR c/61053
+       * c-common.c (min_align_of_type): New function factored out from...
+       (c_sizeof_or_alignof_type): ...here.
+       * c-common.h (min_align_of_type): Declare.
+
 2014-05-08  Marek Polacek  <polacek@redhat.com>
 
        PR c/61077
index 33ad25087731f957e243a871e2b05ab43f53060a..d7c85fcaf7f33742e83715171e3e0ae573fe8ea1 100644 (file)
@@ -4938,6 +4938,26 @@ c_common_get_alias_set (tree t)
   return -1;
 }
 \f
+/* Return the least alignment required for type TYPE.  */
+
+unsigned int
+min_align_of_type (tree type)
+{
+  unsigned int align = TYPE_ALIGN (type);
+  align = MIN (align, BIGGEST_ALIGNMENT);
+#ifdef BIGGEST_FIELD_ALIGNMENT
+  align = MIN (align, BIGGEST_FIELD_ALIGNMENT);
+#endif
+  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);
+#endif
+  align = MIN (align, field_align);
+  return align / BITS_PER_UNIT;
+}
+
 /* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where
    the IS_SIZEOF parameter indicates which operator is being applied.
    The COMPLAIN flag controls whether we should diagnose possibly
@@ -5016,21 +5036,7 @@ c_sizeof_or_alignof_type (location_t loc,
                                size_int (TYPE_PRECISION (char_type_node)
                                          / BITS_PER_UNIT));
       else if (min_alignof)
-       {
-         unsigned int align = TYPE_ALIGN (type);
-         align = MIN (align, BIGGEST_ALIGNMENT);
-#ifdef BIGGEST_FIELD_ALIGNMENT
-         align = MIN (align, BIGGEST_FIELD_ALIGNMENT);
-#endif
-         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);
-#endif
-         align = MIN (align, field_align);
-         value = size_int (align / BITS_PER_UNIT);
-       }
+       value = size_int (min_align_of_type (type));
       else
        value = size_int (TYPE_ALIGN_UNIT (type));
     }
index 57b7dceefdc18d6ff1aea25c7dc3c1e0c3f4fac2..d34d2bb2eb99cd07d97d8450aa092773724c2985 100644 (file)
@@ -758,6 +758,7 @@ extern tree c_wrap_maybe_const (tree, bool);
 extern tree c_save_expr (tree);
 extern tree c_common_truthvalue_conversion (location_t, tree);
 extern void c_apply_type_quals_to_decl (int, tree);
+extern unsigned int min_align_of_type (tree);
 extern tree c_sizeof_or_alignof_type (location_t, tree, bool, bool, int);
 extern tree c_alignof_expr (location_t, tree);
 /* Print an error message for invalid operands to arith operation CODE.
index 892537147d01cf5c647b15404dcf6b952b8aa629..1c8c435f06186fd965fc01518bed669da6cdc423 100644 (file)
@@ -1,3 +1,9 @@
+2014-05-08  Marek Polacek  <polacek@redhat.com>
+
+       PR c/61053
+       * c-decl.c (grokdeclarator): Use min_align_of_type instead of
+       TYPE_ALIGN_UNIT.
+
 2014-05-08  Marek Polacek  <polacek@redhat.com>
 
        PR c/61077
index d8631fc3345012f61d1b9792f999099a1dda8573..d52dcc9b25ba47d3c9279268b7b32b6d4d9620db 100644 (file)
@@ -5931,7 +5931,7 @@ grokdeclarator (const struct c_declarator *declarator,
       else if (declspecs->align_log != -1)
        {
          alignas_align = 1U << declspecs->align_log;
-         if (alignas_align < TYPE_ALIGN_UNIT (type))
+         if (alignas_align < min_align_of_type (type))
            {
              if (name)
                error_at (loc, "%<_Alignas%> specifiers cannot reduce "
index fe0683e511ecff47c7fac0b34652f137e6b8afbb..bbfb333b90d6e42e0efd0d905a881f591fbb1322 100644 (file)
@@ -1,3 +1,8 @@
+2014-05-08  Marek Polacek  <polacek@redhat.com>
+
+       PR c/61053
+       * gcc.dg/pr61053.c: New test.
+
 2014-05-08  Marek Polacek  <polacek@redhat.com>
 
        PR c/61077
diff --git a/gcc/testsuite/gcc.dg/pr61053.c b/gcc/testsuite/gcc.dg/pr61053.c
new file mode 100644 (file)
index 0000000..4fd5319
--- /dev/null
@@ -0,0 +1,75 @@
+/* PR c/61053 */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+_Alignas (char) char cc;
+_Alignas (short int) char cs;
+_Alignas (int) char ci;
+_Alignas (long int) char cl;
+_Alignas (long long int) char cll;
+_Alignas (float) char cf;
+_Alignas (double) char cd;
+_Alignas (long double) char cld;
+
+_Alignas (char) short int sc; /* { dg-error "cannot reduce alignment" } */
+_Alignas (short int) short int ss;
+_Alignas (int) short int si;
+_Alignas (long int) short int sl;
+_Alignas (long long int) short int sll;
+_Alignas (float) short int sf;
+_Alignas (double) short int sd;
+_Alignas (long double) short int sld;
+
+_Alignas (char) int ic; /* { dg-error "cannot reduce alignment" } */
+_Alignas (short int) int is; /* { dg-error "cannot reduce alignment" } */
+_Alignas (int) int ii;
+_Alignas (long int) int il;
+_Alignas (long long int) int ill;
+_Alignas (float) int if_;
+_Alignas (double) int id;
+_Alignas (long double) int ild;
+
+_Alignas (char) long int lic; /* { dg-error "cannot reduce alignment" } */
+_Alignas (short int) long int lis; /* { dg-error "cannot reduce alignment" } */
+_Alignas (int) long int lii; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (long int) long int lil;
+_Alignas (long long int) long int lill;
+_Alignas (float) long int lif; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (double) long int lid;
+_Alignas (long double) long int lild;
+
+_Alignas (char) long long int llic; /* { dg-error "cannot reduce alignment" } */
+_Alignas (short int) long long int llis; /* { dg-error "cannot reduce alignment" } */
+_Alignas (int) long long int llii; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (long int) long long int llil;
+_Alignas (long long int) long long int llill;
+_Alignas (float) long long int llif; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (double) long long int llid;
+_Alignas (long double) long long int llild;
+
+_Alignas (char) float fc; /* { dg-error "cannot reduce alignment" } */
+_Alignas (short int) float fs; /* { dg-error "cannot reduce alignment" } */
+_Alignas (int) float fi;
+_Alignas (long int) float fl;
+_Alignas (long long int) float fll;
+_Alignas (float) float ff;
+_Alignas (double) float fd;
+_Alignas (long double) float fld;
+
+_Alignas (char) double dc; /* { dg-error "cannot reduce alignment" } */
+_Alignas (short int) double ds; /* { dg-error "cannot reduce alignment" } */
+_Alignas (int) double di; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (long int) double dl;
+_Alignas (long long int) double dll;
+_Alignas (float) double df; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (double) double dd;
+_Alignas (long double) double dld;
+
+_Alignas (char) long double ldc; /* { dg-error "cannot reduce alignment" } */
+_Alignas (short int) long double lds; /* { dg-error "cannot reduce alignment" } */
+_Alignas (int) long double ldi; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (long int) long double ldl; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (long long int) long double ldll; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (float) long double ldf; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (double) long double ldd; /* { dg-error "cannot reduce alignment" "" { target { ! { ia32 } } } } */
+_Alignas (long double) long double ldld;