Message ID | Pine.LNX.4.64.1312042257070.21433@digraph.polyomino.org.uk |
---|---|
State | New |
Headers | show |
On Thu, Dec 5, 2013 at 6:57 AM, Joseph S. Myers <joseph@codesourcery.com> wrote: > Index: c-family/c-common.c > =================================================================== > --- c-family/c-common.c (revision 205668) > +++ c-family/c-common.c (working copy) > @@ -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 Won't *field* be unused if ADJUST_FIELD_ALIGN not defined? Thanks, bin
On Thu, 2013-12-05 17:16:53 +0800, Bin.Cheng <amker.cheng@gmail.com> wrote: > On Thu, Dec 5, 2013 at 6:57 AM, Joseph S. Myers <joseph@codesourcery.com> wrote: > > Index: c-family/c-common.c > > =================================================================== > > --- c-family/c-common.c (revision 205668) > > +++ c-family/c-common.c (working copy) > > @@ -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 > > Won't *field* be unused if ADJUST_FIELD_ALIGN not defined? You're right: g++ -c -DIN_GCC_FRONTEND -DIN_GCC_FRONTEND -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -fno-common -DHAVE_CONFIG_H -I. -Ic-family -I../../../gcc/gcc -I../../../gcc/gcc/c-family -I../../../gcc/gcc/../include -I../../../gcc/gcc/../libcpp/include -I/opt/cfarm/mpc/include -I../../../gcc/gcc/../libdecnumber -I../../../gcc/gcc/../libdecnumber/dpd -I../libdecnumber -I../../../gcc/gcc/../libbacktrace -o c-family/c-common.o -MT c-family/c-common.o -MMD -MP -MF c-family/.deps/c-common.TPo ../../../gcc/gcc/c-family/c-common.c ../../../gcc/gcc/c-family/c-common.c: In function ‘tree_node* c_sizeof_or_alignof_type(location_t, tree, bool, bool, int)’: ../../../gcc/gcc/c-family/c-common.c:5007:9: error: unused variable ‘field’ [-Werror=unused-variable] tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, ^ cc1plus: all warnings being treated as errors make[2]: *** [c-family/c-common.o] Error 1 This is m68k-elf, see eg. http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=50551 , but other targets are also affected. MfG, JBG
"Joseph S. Myers" <joseph@codesourcery.com> writes: > @@ -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)); > } ../../gcc/c-family/c-common.c: In function ‘tree_node* c_sizeof_or_alignof_type(location_t, tree, bool, bool, int)’: ../../gcc/c-family/c-common.c:5007:9: error: unused variable ‘field’ [-Werror=unused-variable] tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, ^ Andreas.
Index: objc/objc-act.c =================================================================== --- objc/objc-act.c (revision 205668) +++ objc/objc-act.c (working copy) @@ -7273,6 +7273,7 @@ objc_synthesize_getter (tree klass, tree class_met 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_met 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: c/c-parser.c =================================================================== --- c/c-parser.c (revision 205668) +++ c/c-parser.c (working copy) @@ -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: cp/typeck.c =================================================================== --- cp/typeck.c (revision 205668) +++ cp/typeck.c (working copy) @@ -1562,7 +1562,7 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_c } return c_sizeof_or_alignof_type (input_location, complete_type (type), - op == SIZEOF_EXPR, + op == SIZEOF_EXPR, false, complain); } Index: c-family/c-common.c =================================================================== --- c-family/c-common.c (revision 205668) +++ c-family/c-common.c (working copy) @@ -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)); } Index: c-family/c-common.h =================================================================== --- c-family/c-common.h (revision 205668) +++ c-family/c-common.h (working copy) @@ -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: testsuite/gcc.dg/c11-align-6.c =================================================================== --- testsuite/gcc.dg/c11-align-6.c (revision 0) +++ testsuite/gcc.dg/c11-align-6.c (revision 0) @@ -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); +}