diff options
author | Joseph Myers <joseph@codesourcery.com> | 2013-12-04 22:57:20 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2013-12-04 22:57:20 +0000 |
commit | 21a4ace141473202d8d7601303521a17df99c8e9 (patch) | |
tree | 1d857f76a0338447e2abb6b4d8b9d3a69458fff2 /gcc/c-family/c-common.c | |
parent | 100ba51421005f8f67aca81172c1ae8d33e452f0 (diff) |
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.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@205685 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r-- | gcc/c-family/c-common.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index e652802fde1..a06dea8b7f3 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -4921,14 +4921,17 @@ c_common_get_alias_set (tree t) } /* 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)); } |