]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/52023 ([C11] _Alignof (double) yields wrong value on x86)
authorJoseph Myers <joseph@codesourcery.com>
Wed, 4 Dec 2013 22:57:20 +0000 (22:57 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Wed, 4 Dec 2013 22:57:20 +0000 (22:57 +0000)
PR c/52023
c-family:
* c-common.c (c_sizeof_or_alignof_type): Add parameter min_alignof
and check field alignment if set.
* c-common.h (c_sizeof_or_alignof_type): Update prototype.
(c_sizeof, c_alignof): Update calls to c_sizeof_or_alignof_type.

c:
* c-parser.c (c_parser_alignas_specifier): Use
c_sizeof_or_alignof_type instead of c_alignof.
(c_parser_alignof_expression): Likewise, with min_alignof
parameter depending on alignof spelling used.

cp:
* typeck.c (cxx_sizeof_or_alignof_type): Update call to
c_sizeof_or_alignof_type.

objc:
* objc-act.c (objc_synthesize_getter): Update calls to
c_sizeof_or_alignof_type.

testsuite:
* gcc.dg/c11-align-6.c: New test.

From-SVN: r205685

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/c11-align-6.c [new file with mode: 0644]

index 35c00035e02783aeca40cccac1dbb62be87b17af..875b08d9bea7f33f0a437d2ce5690f1b28c7e17c 100644 (file)
@@ -1,3 +1,11 @@
+2013-12-04  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/52023
+       * c-common.c (c_sizeof_or_alignof_type): Add parameter min_alignof
+       and check field alignment if set.
+       * c-common.h (c_sizeof_or_alignof_type): Update prototype.
+       (c_sizeof, c_alignof): Update calls to c_sizeof_or_alignof_type.
+
 2013-12-04  Jakub Jelinek  <jakub@redhat.com>  
            Marek Polacek  <polacek@redhat.com>
 
index e652802fde180f64b9529611bdadc3341937c9a0..a06dea8b7f36fda0f828cb77734d3af3f84f26a9 100644 (file)
@@ -4921,14 +4921,17 @@ c_common_get_alias_set (tree t)
 }
 \f
 /* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where
-   the second parameter indicates which OPERATOR is being applied.
+   the IS_SIZEOF parameter indicates which operator is being applied.
    The COMPLAIN flag controls whether we should diagnose possibly
    ill-formed constructs or not.  LOC is the location of the SIZEOF or
-   TYPEOF operator.  */
+   TYPEOF operator.  If MIN_ALIGNOF, the least alignment required for
+   a type in any context should be returned, rather than the normal
+   alignment for that type.  */
 
 tree
 c_sizeof_or_alignof_type (location_t loc,
-                         tree type, bool is_sizeof, int complain)
+                         tree type, bool is_sizeof, bool min_alignof,
+                         int complain)
 {
   const char *op_name;
   tree value = NULL;
@@ -4994,6 +4997,22 @@ c_sizeof_or_alignof_type (location_t loc,
        value = size_binop_loc (loc, CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
                                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
+         tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
+                                  type);
+         unsigned int field_align = align;
+#ifdef ADJUST_FIELD_ALIGN
+         field_align = ADJUST_FIELD_ALIGN (field, field_align);
+#endif
+         align = MIN (align, field_align);
+         value = size_int (align / BITS_PER_UNIT);
+       }
       else
        value = size_int (TYPE_ALIGN_UNIT (type));
     }
index 664e9287a1b43ddd09da777e537f00a8aac5ad91..1df9e99243496da91dde3822929f20738d8e2e35 100644 (file)
@@ -759,7 +759,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 tree c_sizeof_or_alignof_type (location_t, tree, bool, int);
+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.
    NOP_EXPR is used as a special case (see truthvalue_conversion).  */
@@ -792,8 +792,8 @@ extern bool keyword_is_type_qualifier (enum rid);
 extern bool keyword_is_decl_specifier (enum rid);
 extern bool cxx_fundamental_alignment_p (unsigned);
 
-#define c_sizeof(LOC, T)  c_sizeof_or_alignof_type (LOC, T, true, 1)
-#define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, 1)
+#define c_sizeof(LOC, T)  c_sizeof_or_alignof_type (LOC, T, true, false, 1)
+#define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, false, 1)
 
 /* Subroutine of build_binary_op, used for certain operations.  */
 extern tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise);
index 0603852fe866871200a66cff94564898d26fc281..4f353e805f03c0712a7911b0f583e9b676dda67e 100644 (file)
@@ -1,3 +1,11 @@
+2013-12-04  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/52023
+       * c-parser.c (c_parser_alignas_specifier): Use
+       c_sizeof_or_alignof_type instead of c_alignof.
+       (c_parser_alignof_expression): Likewise, with min_alignof
+       parameter depending on alignof spelling used.
+
 2013-12-04  Marek Polacek  <polacek@redhat.com>
 
        PR c/54113
index 141c4ce9cf622d3ca0631f3867cf5cc78532fbd3..c78d26909b44fd7e683d5002ed3594bc6fcccb18 100644 (file)
@@ -3045,7 +3045,8 @@ c_parser_alignas_specifier (c_parser * parser)
     {
       struct c_type_name *type = c_parser_type_name (parser);
       if (type != NULL)
-       ret = c_alignof (loc, groktypename (type, NULL, NULL));
+       ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
+                                       false, true, 1);
     }
   else
     ret = c_parser_expr_no_commas (parser, NULL).value;
@@ -6446,11 +6447,12 @@ c_parser_alignof_expression (c_parser *parser)
   location_t loc = c_parser_peek_token (parser)->location;
   tree alignof_spelling = c_parser_peek_token (parser)->value;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
+  bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
+                               "_Alignof") == 0;
   /* A diagnostic is not required for the use of this identifier in
      the implementation namespace; only diagnose it for the C11
      spelling because of existing code using the other spellings.  */
-  if (!flag_isoc11
-      && strcmp (IDENTIFIER_POINTER (alignof_spelling), "_Alignof") == 0)
+  if (!flag_isoc11 && is_c11_alignof)
     {
       if (flag_isoc99)
        pedwarn (loc, OPT_Wpedantic, "ISO C99 does not support %qE",
@@ -6494,7 +6496,9 @@ c_parser_alignof_expression (c_parser *parser)
       /* alignof ( type-name ).  */
       c_inhibit_evaluation_warnings--;
       in_alignof--;
-      ret.value = c_alignof (loc, groktypename (type_name, NULL, NULL));
+      ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
+                                                              NULL, NULL),
+                                           false, is_c11_alignof, 1);
       ret.original_code = ERROR_MARK;
       ret.original_type = NULL;
       return ret;
index 119f309b15c1b422d8ecdd62f393b0d89e9c2841..2583e5e47aa6b5a8efcedd26c425b18c270407b3 100644 (file)
@@ -1,3 +1,9 @@
+2013-12-04  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/52023
+       * typeck.c (cxx_sizeof_or_alignof_type): Update call to
+       c_sizeof_or_alignof_type.
+
 2013-12-04  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/59268
index 9f9f7b6775b6a784da164bf4569837537007454e..74fc4d7b573d4c41091328e1798d8a020570d365 100644 (file)
@@ -1562,7 +1562,7 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
     }
 
   return c_sizeof_or_alignof_type (input_location, complete_type (type),
-                                  op == SIZEOF_EXPR,
+                                  op == SIZEOF_EXPR, false,
                                   complain);
 }
 
index 6ec2ef5fa7070c4ffd2233cd183ba8f230bbfae7..366bc3f5402a137c62fb540615f1f1c53e6a7082 100644 (file)
@@ -1,3 +1,9 @@
+2013-12-04  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/52023
+       * objc-act.c (objc_synthesize_getter): Update calls to
+       c_sizeof_or_alignof_type.
+
 2013-11-22  Andrew MacLeod  <amacleod@redhat.com>
 
        * objc/objc-act.c: Add required include files from gimple.h.
index 2a551ee5857af88e6b4079aff8d591861fb5fb92..4a10f579becd177a3424d46679b072d544ef095c 100644 (file)
@@ -7273,6 +7273,7 @@ objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree pr
             the same type, there is no need to lookup the ivar.  */
          size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
                                              true /* is_sizeof */,
+                                             false /* min_alignof */,
                                              false /* complain */);
 
          if (PROPERTY_NONATOMIC (property))
@@ -7474,6 +7475,7 @@ objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree pr
             the same type, there is no need to lookup the ivar.  */
          size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
                                              true /* is_sizeof */,
+                                             false /* min_alignof */,
                                              false /* complain */);
 
          if (PROPERTY_NONATOMIC (property))
index 6703e6a87ddfd216cf3c20b7135816466263f80b..7779db737db5ab22a1dd5fc1daf166b6d391bba7 100644 (file)
@@ -1,3 +1,8 @@
+2013-12-04  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/52023
+       * gcc.dg/c11-align-6.c: New test.
+
 2013-12-04  Marek Polacek  <polacek@redhat.com>
 
        * c-c++-common/ubsan/overflow-mul-2.c: New test.
diff --git a/gcc/testsuite/gcc.dg/c11-align-6.c b/gcc/testsuite/gcc.dg/c11-align-6.c
new file mode 100644 (file)
index 0000000..7ea994d
--- /dev/null
@@ -0,0 +1,40 @@
+/* Test C11 _Alignof returning minimum alignment for a type.  PR
+   52023.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11" } */
+
+extern void abort (void);
+extern void exit (int);
+
+#define CHECK_ALIGN(TYPE)                      \
+  do                                           \
+    {                                          \
+      struct { char c; TYPE v; } x;            \
+      if (_Alignof (TYPE) > __alignof__ (x.v)) \
+       abort ();                               \
+    }                                          \
+  while (0)
+
+int
+main (void)
+{
+  CHECK_ALIGN (_Bool);
+  CHECK_ALIGN (char);
+  CHECK_ALIGN (signed char);
+  CHECK_ALIGN (unsigned char);
+  CHECK_ALIGN (signed short);
+  CHECK_ALIGN (unsigned short);
+  CHECK_ALIGN (signed int);
+  CHECK_ALIGN (unsigned int);
+  CHECK_ALIGN (signed long);
+  CHECK_ALIGN (unsigned long);
+  CHECK_ALIGN (signed long long);
+  CHECK_ALIGN (unsigned long long);
+  CHECK_ALIGN (float);
+  CHECK_ALIGN (double);
+  CHECK_ALIGN (long double);
+  CHECK_ALIGN (_Complex float);
+  CHECK_ALIGN (_Complex double);
+  CHECK_ALIGN (_Complex long double);
+  exit (0);
+}