On Tue, Apr 10, 2018 at 1:12 PM, Jason Merrill <ja...@redhat.com> wrote:
> But really this is beside the point: the x86 ABI says that the
> alignment of double is 4, so alignof(double) should be 4 regardless of
> what GCC wants to do internally.  And I think the same is true of
> __alignof__.

Particularly since the description of __alignof__ has been clarified:

"Some machines never actually require alignment; they allow reference
to any data type even at an odd address.  For these machines,
'__alignof__' reports the smallest alignment that GCC gives the data
type, usually as mandated by the target ABI."

To that end, here's a patch that makes __alignof__ agree with
_Alignof, fixing bug 10360:
commit 3528a49567a23c0fab5916119e8c4f2dcddd8f3c
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Apr 11 11:09:38 2018 -0400

            PR c/10360 - __alignof__(double) on x86.
    
            PR c++/69763 - wrong alignof(double) on x86.
    gcc/c-family/
            * c-common.c (c_sizeof_or_alignof_type): Always return minimum
            alignment.
            * c-common.h: Remove parameter from prototype.
            (c_sizeof, c_alignof): Remove argument.
    gcc/c/
            * c-parser.c (c_parser_alignas_specifier)
            (c_parser_alignof_expression): Drop min_align argument.
    gcc/cp/
            * typeck.c (cxx_sizeof_or_alignof_type): Drop min_align argument.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 7e6905e791e..5da030916cb 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -3570,7 +3570,7 @@ c_common_get_alias_set (tree t)
 
 tree
 c_sizeof_or_alignof_type (location_t loc,
-			  tree type, bool is_sizeof, bool min_alignof,
+			  tree type, bool is_sizeof,
 			  int complain)
 {
   const char *op_name;
@@ -3637,10 +3637,8 @@ 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)
+      else
 	value = size_int (min_align_of_type (type));
-      else
-	value = size_int (TYPE_ALIGN_UNIT (type));
     }
 
   /* VALUE will have the middle-end integer type sizetype.
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 6cf7614f682..db04ce6cf6a 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -827,7 +827,7 @@ extern tree c_fully_fold (tree, bool, bool *, bool = false);
 extern tree c_wrap_maybe_const (tree, bool);
 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, bool, int);
+extern tree c_sizeof_or_alignof_type (location_t, tree, 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).  */
@@ -854,8 +854,8 @@ extern tree fold_for_warn (tree);
 extern tree c_common_get_narrower (tree, int *);
 extern bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *);
 
-#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)
+#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)
 
 /* Subroutine of build_binary_op, used for certain operations.  */
 extern tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 47720861d3f..53e120071d9 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -3513,7 +3513,7 @@ c_parser_alignas_specifier (c_parser * parser)
       struct c_type_name *type = c_parser_type_name (parser);
       if (type != NULL)
 	ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
-					false, true, 1);
+					false, 1);
     }
   else
     ret = c_parser_expr_no_commas (parser, NULL).value;
@@ -7406,7 +7406,7 @@ c_parser_alignof_expression (c_parser *parser)
       in_alignof--;
       ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
 							       NULL, NULL),
-					    false, is_c11_alignof, 1);
+					    false, 1);
       ret.original_code = ERROR_MARK;
       ret.original_type = NULL;
       set_c_expr_source_range (&ret, start_loc, end_loc);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 1e6996cde09..bf71d7458a8 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1641,8 +1641,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, true,
-				   complain);
+				   op == SIZEOF_EXPR, complain);
 }
 
 /* Return the size of the type, without producing any warnings for

Reply via email to