From 673670da1e5dae2aaccbade88d540cf0200f0eb3 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 29 Nov 2018 17:48:58 +0000 Subject: [PATCH] PR c/88172 - attribute aligned of zero silently accepted but ignored PR c/88172 - attribute aligned of zero silently accepted but ignored PR testsuite/88208 - new test case c-c++-common/builtin-has-attribute-3.c in r266335 has multiple excess errors gcc/ChangeLog: PR c/88172 PR testsuite/88208 * doc/extend.texi (attribute constructor): Clarify. gcc/c/ChangeLog: PR c/88172 PR testsuite/88208 * c-decl.c (declspec_add_alignas): Adjust call to check_user_alignment. gcc/c-family/ChangeLog: PR c/88172 PR testsuite/88208 * c-attribs.c (common_handle_aligned_attribute): Silently avoid setting alignments to values less than the target requires. (has_attribute): For attribute aligned consider both the attribute and the alignment bits. * c-common.c (c_init_attributes): Optionally issue a warning for zero alignment. gcc/testsuite/ChangeLog: PR c/88172 PR testsuite/88208 * gcc.dg/attr-aligned-2.c: New test. * gcc.dg/builtin-has-attribute.c: Adjust. * c-c++-common/builtin-has-attribute-2.c: Same. * c-c++-common/builtin-has-attribute-3.c: Same. * c-c++-common/builtin-has-attribute-4.c: Same. * c-c++-common/builtin-has-attribute-5.c: New test. * gcc.target/aarch64/attr-aligned.c: Same. * gcc.target/i386/attr-aligned.c: Same. * gcc.target/powerpc/attr-aligned.c: Same. * gcc.target/sparc/attr-aligned.c: Same. From-SVN: r266633 --- gcc/ChangeLog | 6 ++ gcc/c-family/ChangeLog | 11 +++ gcc/c-family/c-attribs.c | 98 ++++++++++++---------- gcc/c-family/c-common.c | 16 ++-- gcc/c/ChangeLog | 6 ++ gcc/c/c-decl.c | 7 +- gcc/doc/extend.texi | 9 +- gcc/testsuite/ChangeLog | 15 ++++ .../c-c++-common/builtin-has-attribute-2.c | 8 +- .../c-c++-common/builtin-has-attribute-3.c | 20 +---- .../c-c++-common/builtin-has-attribute-4.c | 8 +- .../c-c++-common/builtin-has-attribute-5.c | 48 +++++++++++ gcc/testsuite/gcc.dg/attr-aligned-2.c | 21 +++++ gcc/testsuite/gcc.dg/builtin-has-attribute.c | 17 ++-- gcc/testsuite/gcc.target/aarch64/attr-aligned.c | 65 ++++++++++++++ gcc/testsuite/gcc.target/i386/attr-aligned.c | 65 ++++++++++++++ gcc/testsuite/gcc.target/powerpc/attr-aligned.c | 65 ++++++++++++++ gcc/testsuite/gcc.target/sparc/attr-aligned.c | 65 ++++++++++++++ 18 files changed, 467 insertions(+), 83 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/builtin-has-attribute-5.c create mode 100644 gcc/testsuite/gcc.dg/attr-aligned-2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/attr-aligned.c create mode 100644 gcc/testsuite/gcc.target/i386/attr-aligned.c create mode 100644 gcc/testsuite/gcc.target/powerpc/attr-aligned.c create mode 100644 gcc/testsuite/gcc.target/sparc/attr-aligned.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 02c2403..bc8d2b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-11-29 Martin Sebor + + PR c/88172 + PR testsuite/88208 + * doc/extend.texi (attribute constructor): Clarify. + 2018-11-29 Martin Liska PR middle-end/88246 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index ee193d9..890b014 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,14 @@ +2018-11-29 Martin Sebor + + PR c/88172 + PR testsuite/88208 + * c-attribs.c (common_handle_aligned_attribute): Silently avoid setting + alignments to values less than the target requires. + (has_attribute): For attribute aligned consider both the attribute + and the alignment bits. + * c-common.c (c_init_attributes): Optionally issue a warning for + zero alignment. + 2018-11-28 Martin Sebor PR c/88065 diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 373381d..1454e2f 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -2003,7 +2003,8 @@ common_handle_aligned_attribute (tree *node, tree name, tree args, int flags, bool objfile = (TREE_CODE (*node) == FUNCTION_DECL || (VAR_P (*node) && TREE_STATIC (*node))); /* Log2 of specified alignment. */ - int pow2align = check_user_alignment (align_expr, objfile, true); + int pow2align = check_user_alignment (align_expr, objfile, + /* warn_zero = */ true); if (pow2align == -1 || !check_cxx_fundamental_alignment_constraints (*node, pow2align, flags)) { @@ -2019,6 +2020,9 @@ common_handle_aligned_attribute (tree *node, tree name, tree args, int flags, unsigned curalign = 0; unsigned lastalign = 0; + /* True when SET_DECL_ALIGN() should be called for the decl when + *NO_ADD_ATTRS is false. */ + bool set_align = true; if (is_type) { if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) @@ -2067,23 +2071,35 @@ common_handle_aligned_attribute (tree *node, tree name, tree args, int flags, curalign = lastalign; curalign /= BITS_PER_UNIT; - bitalign /= BITS_PER_UNIT; + unsigned newalign = bitalign / BITS_PER_UNIT; - bool diagd = true; auto_diagnostic_group d; - if (DECL_USER_ALIGN (decl) || DECL_USER_ALIGN (last_decl)) - diagd = warning (OPT_Wattributes, - "ignoring attribute %<%E (%u)%> because it conflicts " - "with attribute %<%E (%u)%>", - name, bitalign, name, curalign); + if ((DECL_USER_ALIGN (decl) + || DECL_USER_ALIGN (last_decl))) + { + if (warning (OPT_Wattributes, + "ignoring attribute %<%E (%u)%> because it conflicts " + "with attribute %<%E (%u)%>", + name, newalign, name, curalign) + && note) + inform (DECL_SOURCE_LOCATION (last_decl), + "previous declaration here"); + /* Only reject attempts to relax/override an alignment + explicitly specified previously and accept declarations + that appear to relax the implicit function alignment for + the target. Both increasing and increasing the alignment + set by -falign-functions setting is permitted. */ + *no_add_attrs = true; + } else if (!warn_if_not_aligned_p) - /* Do not error out for attribute warn_if_not_aligned. */ - error ("alignment for %q+D must be at least %d", decl, curalign); - - if (diagd && note) - inform (DECL_SOURCE_LOCATION (last_decl), "previous declaration here"); - - *no_add_attrs = true; + { + /* Do not fail for attribute warn_if_not_aligned. Otherwise, + silently avoid applying the alignment to the declaration + because it's implicitly satisfied by the target. Apply + the attribute nevertheless so it can be retrieved by + __builtin_has_attribute. */ + set_align = false; + } } else if (DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) > bitalign) @@ -2100,33 +2116,29 @@ common_handle_aligned_attribute (tree *node, tree name, tree args, int flags, && TREE_CODE (decl) == FUNCTION_DECL && DECL_ALIGN (decl) > bitalign) { - /* Don't warn function alignment here if warn_if_not_aligned_p is - true. It will be warned later. */ + /* Don't warn for function alignment here if warn_if_not_aligned_p + is true. It will be warned about later. */ if (DECL_USER_ALIGN (decl)) - error ("alignment for %q+D was previously specified as %d " - "and may not be decreased", decl, - DECL_ALIGN (decl) / BITS_PER_UNIT); - else - error ("alignment for %q+D must be at least %d", decl, - DECL_ALIGN (decl) / BITS_PER_UNIT); - *no_add_attrs = true; - } - else - { - if (warn_if_not_aligned_p) - { - if (TREE_CODE (decl) == FIELD_DECL && !DECL_C_BIT_FIELD (decl)) - { - SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign); - warn_if_not_aligned_p = false; - } - } - else { - SET_DECL_ALIGN (decl, bitalign); - DECL_USER_ALIGN (decl) = 1; + /* Only reject attempts to relax/override an alignment + explicitly specified previously and accept declarations + that appear to relax the implicit function alignment for + the target. Both increasing and increasing the alignment + set by -falign-functions setting is permitted. */ + error ("alignment for %q+D was previously specified as %d " + "and may not be decreased", decl, + DECL_ALIGN (decl) / BITS_PER_UNIT); + *no_add_attrs = true; } } + else if (warn_if_not_aligned_p + && TREE_CODE (decl) == FIELD_DECL + && !DECL_C_BIT_FIELD (decl)) + { + SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign); + warn_if_not_aligned_p = false; + set_align = false; + } if (warn_if_not_aligned_p) { @@ -2134,6 +2146,11 @@ common_handle_aligned_attribute (tree *node, tree name, tree args, int flags, decl); *no_add_attrs = true; } + else if (!is_type && !*no_add_attrs && set_align) + { + SET_DECL_ALIGN (decl, bitalign); + DECL_USER_ALIGN (decl) = 1; + } return NULL_TREE; } @@ -4086,11 +4103,6 @@ has_attribute (location_t atloc, tree t, tree attr, tree (*convert)(tree)) with the sought attributes) has been found on the attribute chain. */ bool found_attr = false; - /* For attribute aligned ignore the attribute list and consider - the tree node itself instead. */ - if (type && !strcmp ("aligned", namestr)) - atlist = NULL_TREE; - /* When clear, the first mismatched attribute argument results in failure. Otherwise, the first matched attribute argument results in success. */ diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 9d51815..4c90365 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -5143,11 +5143,11 @@ c_init_attributes (void) then reject alignments greater than MAX_OFILE_ALIGNMENT when converted to bits. Otherwise, consider valid only alignments that are less than HOST_BITS_PER_INT - LOG2_BITS_PER_UNIT. - If ALLOW_ZERO then 0 is valid and should result in - a return of -1 with no error. */ + Zero is not considered a valid argument (and results in -1 on + return) but it only triggers a warning when WARN_ZERO is set. */ int -check_user_alignment (const_tree align, bool objfile, bool allow_zero) +check_user_alignment (const_tree align, bool objfile, bool warn_zero) { if (error_operand_p (align)) return -1; @@ -5159,8 +5159,14 @@ check_user_alignment (const_tree align, bool objfile, bool allow_zero) return -1; } - if (allow_zero && integer_zerop (align)) - return -1; + if (integer_zerop (align)) + { + if (warn_zero) + warning (OPT_Wattributes, + "requested alignment %qE is not a positive power of 2", + align); + return -1; + } int log2bitalign; if (tree_int_cst_sgn (align) == -1 diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index bcb282c..4ed5b4b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2018-11-29 Martin Sebor + + PR c/88172 + PR testsuite/88208 + * c-decl.c (declspec_add_alignas): Adjust call to check_user_alignment. + 2018-11-23 Martin Sebor PR testsuite/88098 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index cdd10ab..b50f2bf 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -11061,12 +11061,15 @@ struct c_declspecs * declspecs_add_alignas (location_t loc, struct c_declspecs *specs, tree align) { - int align_log; specs->alignas_p = true; specs->locations[cdw_alignas] = loc; if (align == error_mark_node) return specs; - align_log = check_user_alignment (align, false, true); + + /* Only accept the alignment if it's valid and greater than + the current one. Zero is invalid but by C11 required to + be silently ignored. */ + int align_log = check_user_alignment (align, false, /* warn_zero = */false); if (align_log > specs->align_log) specs->align_log = align_log; return specs; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 4e8be5b..8c7b178 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2552,8 +2552,9 @@ called. Functions with these attributes are useful for initializing data that is used implicitly during the execution of the program. -You may provide an optional integer priority to control the order in -which constructor and destructor functions are run. A constructor +On some targets the attributes also accept an integer argument to +specify a priority to control the order in which constructor and +destructor functions are run. A constructor with a smaller priority number runs before a constructor with a larger priority number; the opposite relationship holds for destructors. So, if you have a constructor that allocates a resource and a destructor @@ -2566,6 +2567,10 @@ decorated with attribute @code{constructor} are invoked is unspecified. In mixed declarations, attribute @code{init_priority} can be used to impose a specific ordering. +Using the argument forms of the @code{constructor} and @code{destructor} +attributes on targets where the feature is not supported is rejected with +an error. + @item copy @itemx copy (@var{function}) @cindex @code{copy} function attribute diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5dcc0b4..ecb1ad6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2018-11-29 Martin Sebor + + PR c/88172 + PR testsuite/88208 + * gcc.dg/attr-aligned-2.c: New test. + * gcc.dg/builtin-has-attribute.c: Adjust. + * c-c++-common/builtin-has-attribute-2.c: Same. + * c-c++-common/builtin-has-attribute-3.c: Same. + * c-c++-common/builtin-has-attribute-4.c: Same. + * c-c++-common/builtin-has-attribute-5.c: New test. + * gcc.target/aarch64/attr-aligned.c: Same. + * gcc.target/i386/attr-aligned.c: Same. + * gcc.target/powerpc/attr-aligned.c: Same. + * gcc.target/sparc/attr-aligned.c: Same. + 2018-11-29 qing zhao * gcc.dg/live-patching-1.c: New test. diff --git a/gcc/testsuite/c-c++-common/builtin-has-attribute-2.c b/gcc/testsuite/c-c++-common/builtin-has-attribute-2.c index 0f692ff..f842241 100644 --- a/gcc/testsuite/c-c++-common/builtin-has-attribute-2.c +++ b/gcc/testsuite/c-c++-common/builtin-has-attribute-2.c @@ -42,8 +42,8 @@ void test_type (int n) A (0, int ATTR (aligned (4)), aligned (2)); A (0, int ATTR (aligned (2)), aligned (4)); - /* GCC retains both attributes in the */ - A (0, int ATTR (aligned (2), aligned (4)), aligned (2)); + /* GCC retains both attributes when the type is defined in the builtin. */ + A (1, int ATTR (aligned (2), aligned (4)), aligned (2)); A (1, int ATTR (aligned (2), aligned (4)), aligned (4)); /* The following fails due to bug 87524. A (1, int ATTR (aligned (4), aligned (2))), aligned (4)); */ @@ -132,7 +132,7 @@ void test_typedef (int n) A (1, MAI, may_alias); typedef ATTR (aligned (4), may_alias) char A4MAC; - A (0, A4MAC, aligned (0)); + A (0, A4MAC, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (0, A4MAC, aligned (1)); A (0, A4MAC, aligned (2)); A (1, A4MAC, aligned (4)); @@ -141,7 +141,7 @@ void test_typedef (int n) typedef ATTR (may_alias, aligned (8)) char A8MAC; A (1, A8MAC, aligned); - A (0, A8MAC, aligned (0)); + A (0, A8MAC, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (0, A8MAC, aligned (1)); A (0, A8MAC, aligned (2)); A (0, A8MAC, aligned (4)); diff --git a/gcc/testsuite/c-c++-common/builtin-has-attribute-3.c b/gcc/testsuite/c-c++-common/builtin-has-attribute-3.c index 237dc72..f048059 100644 --- a/gcc/testsuite/c-c++-common/builtin-has-attribute-3.c +++ b/gcc/testsuite/c-c++-common/builtin-has-attribute-3.c @@ -35,7 +35,7 @@ ATTR (alias ("fnoreturn")) void falias (void); void test_aligned (void) { A (0, fnone, aligned); - A (0, fnone, aligned (0)); + A (0, fnone, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (0, fnone, aligned (1)); A (0, fnone, aligned (2)); A (0, fnone, aligned (4)); @@ -43,18 +43,18 @@ void test_aligned (void) A (0, fnone, aligned (16)); A (1, faligned, aligned); - A (0, faligned, aligned (0)); + A (0, faligned, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (0, faligned, aligned (1)); A (0, faligned, aligned (2)); A (1, faligned_1, aligned); - A (0, faligned_1, aligned (0)); + A (0, faligned_1, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (1, faligned_1, aligned (1)); A (0, faligned_1, aligned (2)); A (0, faligned_1, aligned (4)); A (1, faligned_2, aligned); - A (0, faligned_2, aligned (0)); + A (0, faligned_2, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (0, faligned_2, aligned (1)); A (1, faligned_2, aligned (2)); A (0, faligned_2, aligned (4)); @@ -193,18 +193,6 @@ void test_ctor_dtor (void) A (1, fctor_dtor, constructor); A (1, fctor_dtor, destructor); - - extern ATTR (constructor (123)) void fctor_123 (void); - A (1, fctor_123, constructor); - A (0, fctor_123, destructor); - A (1, fctor_123, constructor (123)); - A (0, fctor_123, constructor (124)); - - extern ATTR (destructor (234)) void fctor_123 (void); - A (1, fctor_123, constructor (123)); - A (1, fctor_123, destructor); - A (1, fctor_123, destructor (234)); - A (0, fctor_123, destructor (235)); } diff --git a/gcc/testsuite/c-c++-common/builtin-has-attribute-4.c b/gcc/testsuite/c-c++-common/builtin-has-attribute-4.c index 14bdd3f..d56ef6b 100644 --- a/gcc/testsuite/c-c++-common/builtin-has-attribute-4.c +++ b/gcc/testsuite/c-c++-common/builtin-has-attribute-4.c @@ -19,7 +19,7 @@ ATTR (aligned (8)) char valigned_8; void test_aligned (void) { A (0, vnone, aligned); - A (0, vnone, aligned (0)); + A (0, vnone, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (0, vnone, aligned (1)); A (0, vnone, aligned (2)); A (0, vnone, aligned (4)); @@ -27,18 +27,18 @@ void test_aligned (void) A (0, vnone, aligned (16)); A (1, valigned, aligned); - A (0, valigned, aligned (0)); + A (0, valigned, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (0, valigned, aligned (1)); A (0, valigned, aligned (2)); A (1, valigned_1, aligned); - A (0, valigned_1, aligned (0)); + A (0, valigned_1, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (1, valigned_1, aligned (1)); A (0, valigned_1, aligned (2)); A (0, valigned_1, aligned (4)); A (1, valigned_2, aligned); - A (0, valigned_2, aligned (0)); + A (0, valigned_2, aligned (0)); /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ A (0, valigned_2, aligned (1)); A (1, valigned_2, aligned (2)); A (0, valigned_2, aligned (4)); diff --git a/gcc/testsuite/c-c++-common/builtin-has-attribute-5.c b/gcc/testsuite/c-c++-common/builtin-has-attribute-5.c new file mode 100644 index 0000000..20d95d8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/builtin-has-attribute-5.c @@ -0,0 +1,48 @@ +/* Verify __builtin_has_attribute return value for attributes constructor + and destructor with explicit priorities. + { dg-do compile { target init_priority } } + { dg-options "-Wall -ftrack-macro-expansion=0" } + { dg-options "-Wall -Wno-narrowing -Wno-unused -ftrack-macro-expansion=0" { target c++ } } */ + +#define ATTR(...) __attribute__ ((__VA_ARGS__)) + +#define A(expect, sym, attr) \ + typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)] + +void fnone (void); + +void test_ctor_dtor_prio (void) +{ + extern ATTR (constructor) void fctor (void); + extern ATTR (destructor) void fdtor (void); + extern ATTR (constructor, destructor) void fctor_dtor (void); + + A (0, fnone, constructor); + A (0, fnone, constructor (123)); + A (0, fnone, destructor); + A (0, fnone, constructor (234)); + + A (1, fctor, constructor); + A (0, fctor, constructor (123)); + A (1, fdtor, destructor); + A (0, fdtor, destructor (234)); + + extern ATTR (constructor) void fctor_dtor (void); + extern ATTR (destructor) void fctor_dtor (void); + extern ATTR (constructor, destructor) void fctor_dtor (void); + + A (1, fctor_dtor, constructor); + A (1, fctor_dtor, destructor); + + extern ATTR (constructor (123)) void fctor_123 (void); + A (1, fctor_123, constructor); + A (0, fctor_123, destructor); + A (1, fctor_123, constructor (123)); + A (0, fctor_123, constructor (124)); + + extern ATTR (destructor (234)) void fctor_123 (void); + A (1, fctor_123, constructor (123)); + A (1, fctor_123, destructor); + A (1, fctor_123, destructor (234)); + A (0, fctor_123, destructor (235)); +} diff --git a/gcc/testsuite/gcc.dg/attr-aligned-2.c b/gcc/testsuite/gcc.dg/attr-aligned-2.c new file mode 100644 index 0000000..ff6516c --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-aligned-2.c @@ -0,0 +1,21 @@ +/* PR c/88172 - attribute aligned of zero silently accepted but ignored + Verify that valid alignment on functions is accepted for all targets + and that alignment of zero is ignored with a warning. + { dg-do compile } + { dg-options "-Wno-pedantic" } */ + +#define ASSERT(expr) _Static_assert (expr, #expr) +#define ALIGN(n) __attribute__ ((aligned (n))) +#define alignof(expr) __alignof__ (expr) + +ALIGN (0) void f0 (void) { } /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ +ALIGN (1) void f1 (void) { } +ALIGN (2) void f2 (void) { } +ALIGN (3) void f3 (void) { } /* { dg-error "requested alignment '3' is not a positive power of 2" } */ +ALIGN (4) void f4 (void) { } + +ASSERT (alignof (f0) > 0); +ASSERT (alignof (f1) >= 1); +ASSERT (alignof (f2) >= 2); +ASSERT (alignof (f3) >= 1); +ASSERT (alignof (f4) >= 4); diff --git a/gcc/testsuite/gcc.dg/builtin-has-attribute.c b/gcc/testsuite/gcc.dg/builtin-has-attribute.c index 8c11cf8..9668ace 100644 --- a/gcc/testsuite/gcc.dg/builtin-has-attribute.c +++ b/gcc/testsuite/gcc.dg/builtin-has-attribute.c @@ -3,16 +3,14 @@ Also verify that the expression in __builtin_has_attribute is not evaluated. - { dg-do run } - { dg-options "-O2 -Wall -Wc++-compat" } */ + { dg-do compile } + { dg-options "-O2 -Wall -Wc++-compat -fdump-tree-optimized -ftrack-macro-expansion=0" } */ #define ATTR(list) __attribute__ (list) #define A(expect, sym, attr) \ typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)] -int nfails; - #define assert(expr) \ ((expr) \ ? (void)0 \ @@ -24,22 +22,27 @@ A (0, struct A { int i; }, aligned); /* { dg-warning "expression is invalid in A (1, struct ATTR ((aligned)) B { int i; }, aligned); /* { dg-warning "expression is invalid in C\\\+\\\+" } */ -int f (void) +static int f (void) { __builtin_abort (); } -int n = 1; - int main (void) { + int n = 0, nfails = 0; + assert (0 == __builtin_has_attribute (int[n++], aligned)); assert (1 == __builtin_has_attribute (ATTR ((aligned)) int[n++], aligned)); assert (1 == __builtin_has_attribute (ATTR ((aligned)) int[f ()], aligned)); assert (1 == 1); + if (n) + __builtin_abort (); + if (nfails) __builtin_abort (); return 0; } + +/* { dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/attr-aligned.c b/gcc/testsuite/gcc.target/aarch64/attr-aligned.c new file mode 100644 index 0000000..fe37dba --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/attr-aligned.c @@ -0,0 +1,65 @@ +/* Verify that valid alignment on functions is accepted and results + in the alignment expected for the target and that alignment of + zero is ignored with a warning. + { dg-do compile } + { dg-options "-Wno-pedantic -ftrack-macro-expansion=0" } */ + +#define ASSERT(expr) _Static_assert (expr, #expr) +#define ALIGN(n) __attribute__ ((aligned (n))) +#define alignof(expr) __alignof__ (expr) +#define HAS_ALIGN(f, n) __builtin_has_attribute (f, __aligned__ (n)) + +#define MINALIGN(N) ((N) < 4 ? 4 : (N)) +#define MAXALIGN 16 + +/* No alignment specified. */ +void f (void) { } + +/* Empty alignment means maximum. */ +ALIGN () void f_ (void) { } + +ALIGN (0) void f0 (void) { } /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ +ALIGN (1) void f1 (void) { } +ALIGN (2) void f2 (void) { } +ALIGN (4) void f4 (void) { } +ALIGN (8) void f8 (void) { } +ALIGN (16) void f16 (void) { } +ALIGN (32) void f32 (void) { } + +ASSERT (alignof (f_) == MAXALIGN); +ASSERT (alignof (f0) == alignof (f)); +ASSERT (alignof (f1) == MINALIGN (1)); +ASSERT (alignof (f2) == MINALIGN (2)); +ASSERT (alignof (f4) == MINALIGN (4)); +ASSERT (alignof (f8) == MINALIGN (8)); +ASSERT (alignof (f16) == MINALIGN (16)); +ASSERT (alignof (f32) == MINALIGN (32)); + +ASSERT (!__builtin_has_attribute (f, aligned)); +ASSERT (__builtin_has_attribute (f_, aligned)); +ASSERT (!__builtin_has_attribute (f0, aligned)); + +ASSERT (!HAS_ALIGN (f_, MAXALIGN)); + +ASSERT (HAS_ALIGN (f1, 1)); +ASSERT (!HAS_ALIGN (f1, 2)); + +ASSERT (!HAS_ALIGN (f2, 1)); +ASSERT (HAS_ALIGN (f2, 2)); +ASSERT (!HAS_ALIGN (f2, 4)); + +ASSERT (!HAS_ALIGN (f4, 2)); +ASSERT (HAS_ALIGN (f4, 4)); +ASSERT (!HAS_ALIGN (f4, 8)); + +ASSERT (!HAS_ALIGN (f8, 4)); +ASSERT (HAS_ALIGN (f8, 8)); +ASSERT (!HAS_ALIGN (f8, 16)); + +ASSERT (!HAS_ALIGN (f16, 8)); +ASSERT (HAS_ALIGN (f16, 16)); +ASSERT (!HAS_ALIGN (f16, 32)); + +ASSERT (!HAS_ALIGN (f32, 16)); +ASSERT (HAS_ALIGN (f32, 32)); +ASSERT (!HAS_ALIGN (f32, 64)); diff --git a/gcc/testsuite/gcc.target/i386/attr-aligned.c b/gcc/testsuite/gcc.target/i386/attr-aligned.c new file mode 100644 index 0000000..1ed9c8c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/attr-aligned.c @@ -0,0 +1,65 @@ +/* Verify that valid alignment on functions is accepted and results + in the alignment expected for the target and that alignment of + zero is ignored with a warning. + { dg-do compile } + { dg-options "-Wno-pedantic -ftrack-macro-expansion=0" } */ + +#define ASSERT(expr) _Static_assert (expr, #expr) +#define ALIGN(n) __attribute__ ((aligned (n))) +#define alignof(expr) __alignof__ (expr) +#define HAS_ALIGN(f, n) __builtin_has_attribute (f, __aligned__ (n)) + +#define MINALIGN(N) N +#define MAXALIGN 16 + +/* No alignment specified. */ +void f (void) { } + +/* Empty alignment means maximum. */ +ALIGN () void f_ (void) { } + +ALIGN (0) void f0 (void) { } /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ +ALIGN (1) void f1 (void) { } +ALIGN (2) void f2 (void) { } +ALIGN (4) void f4 (void) { } +ALIGN (8) void f8 (void) { } +ALIGN (16) void f16 (void) { } +ALIGN (32) void f32 (void) { } + +ASSERT (alignof (f_) == MAXALIGN); +ASSERT (alignof (f0) == alignof (f)); +ASSERT (alignof (f1) == MINALIGN (1)); +ASSERT (alignof (f2) == MINALIGN (2)); +ASSERT (alignof (f4) == MINALIGN (4)); +ASSERT (alignof (f8) == MINALIGN (8)); +ASSERT (alignof (f16) == MINALIGN (16)); +ASSERT (alignof (f32) == MINALIGN (32)); + +ASSERT (!__builtin_has_attribute (f, aligned)); +ASSERT (__builtin_has_attribute (f_, aligned)); +ASSERT (!__builtin_has_attribute (f0, aligned)); + +ASSERT (!HAS_ALIGN (f_, MAXALIGN)); + +ASSERT (HAS_ALIGN (f1, 1)); +ASSERT (!HAS_ALIGN (f1, 2)); + +ASSERT (!HAS_ALIGN (f2, 1)); +ASSERT (HAS_ALIGN (f2, 2)); +ASSERT (!HAS_ALIGN (f2, 4)); + +ASSERT (!HAS_ALIGN (f4, 2)); +ASSERT (HAS_ALIGN (f4, 4)); +ASSERT (!HAS_ALIGN (f4, 8)); + +ASSERT (!HAS_ALIGN (f8, 4)); +ASSERT (HAS_ALIGN (f8, 8)); +ASSERT (!HAS_ALIGN (f8, 16)); + +ASSERT (!HAS_ALIGN (f16, 8)); +ASSERT (HAS_ALIGN (f16, 16)); +ASSERT (!HAS_ALIGN (f16, 32)); + +ASSERT (!HAS_ALIGN (f32, 16)); +ASSERT (HAS_ALIGN (f32, 32)); +ASSERT (!HAS_ALIGN (f32, 64)); diff --git a/gcc/testsuite/gcc.target/powerpc/attr-aligned.c b/gcc/testsuite/gcc.target/powerpc/attr-aligned.c new file mode 100644 index 0000000..4b5b666 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/attr-aligned.c @@ -0,0 +1,65 @@ +/* Verify that valid alignment on functions is accepted and results + in the alignment expected for the target and that alignment of + zero is ignored with a warning. + { dg-do compile } + { dg-options "-Wno-pedantic -ftrack-macro-expansion=0" } */ + +#define ASSERT(expr) _Static_assert (expr, #expr) +#define ALIGN(n) __attribute__ ((aligned (n))) +#define alignof(expr) __alignof__ (expr) +#define HAS_ALIGN(f, n) __builtin_has_attribute (f, __aligned__ (n)) + +#define MINALIGN(N) (N < 4 ? 4 : N) +#define MAXALIGN 16 + +/* No alignment specified. */ +void f (void) { } + +/* Empty alignment means maximum. */ +ALIGN () void f_ (void) { } + +ALIGN (0) void f0 (void) { } /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ +ALIGN (1) void f1 (void) { } +ALIGN (2) void f2 (void) { } +ALIGN (4) void f4 (void) { } +ALIGN (8) void f8 (void) { } +ALIGN (16) void f16 (void) { } +ALIGN (32) void f32 (void) { } + +ASSERT (alignof (f_) == MAXALIGN); +ASSERT (alignof (f0) == alignof (f)); +ASSERT (alignof (f1) == MINALIGN (1)); +ASSERT (alignof (f2) == MINALIGN (2)); +ASSERT (alignof (f4) == MINALIGN (4)); +ASSERT (alignof (f8) == MINALIGN (8)); +ASSERT (alignof (f16) == MINALIGN (16)); +ASSERT (alignof (f32) == MINALIGN (32)); + +ASSERT (!__builtin_has_attribute (f, aligned)); +ASSERT (__builtin_has_attribute (f_, aligned)); +ASSERT (!__builtin_has_attribute (f0, aligned)); + +ASSERT (!HAS_ALIGN (f_, MAXALIGN)); + +ASSERT (HAS_ALIGN (f1, 1)); +ASSERT (!HAS_ALIGN (f1, 2)); + +ASSERT (!HAS_ALIGN (f2, 1)); +ASSERT (HAS_ALIGN (f2, 2)); +ASSERT (!HAS_ALIGN (f2, 4)); + +ASSERT (!HAS_ALIGN (f4, 2)); +ASSERT (HAS_ALIGN (f4, 4)); +ASSERT (!HAS_ALIGN (f4, 8)); + +ASSERT (!HAS_ALIGN (f8, 4)); +ASSERT (HAS_ALIGN (f8, 8)); +ASSERT (!HAS_ALIGN (f8, 16)); + +ASSERT (!HAS_ALIGN (f16, 8)); +ASSERT (HAS_ALIGN (f16, 16)); +ASSERT (!HAS_ALIGN (f16, 32)); + +ASSERT (!HAS_ALIGN (f32, 16)); +ASSERT (HAS_ALIGN (f32, 32)); +ASSERT (!HAS_ALIGN (f32, 64)); diff --git a/gcc/testsuite/gcc.target/sparc/attr-aligned.c b/gcc/testsuite/gcc.target/sparc/attr-aligned.c new file mode 100644 index 0000000..7dc9b19 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/attr-aligned.c @@ -0,0 +1,65 @@ +/* Verify that valid alignment on functions is accepted and results + in the alignment expected for the target and that alignment of + zero is ignored with a warning. + { dg-do compile } + { dg-options "-Wno-pedantic -ftrack-macro-expansion=0" } */ + +#define ASSERT(expr) _Static_assert (expr, #expr) +#define ALIGN(n) __attribute__ ((aligned (n))) +#define alignof(expr) __alignof__ (expr) +#define HAS_ALIGN(f, n) __builtin_has_attribute (f, __aligned__ (n)) + +#define MINALIGN(N) ((N) < 4 ? 4 : (N)) +#define MAXALIGN 8 + +/* No alignment specified. */ +void f (void) { } + +/* Empty alignment means maximum. */ +ALIGN () void f_ (void) { } + +ALIGN (0) void f0 (void) { } /* { dg-warning "requested alignment .0. is not a positive power of 2" } */ +ALIGN (1) void f1 (void) { } +ALIGN (2) void f2 (void) { } +ALIGN (4) void f4 (void) { } +ALIGN (8) void f8 (void) { } +ALIGN (16) void f16 (void) { } +ALIGN (32) void f32 (void) { } + +ASSERT (alignof (f_) == MAXALIGN); +ASSERT (alignof (f0) == alignof (f)); +ASSERT (alignof (f1) == MINALIGN (1)); +ASSERT (alignof (f2) == MINALIGN (2)); +ASSERT (alignof (f4) == MINALIGN (4)); +ASSERT (alignof (f8) == MINALIGN (8)); +ASSERT (alignof (f16) == MINALIGN (16)); +ASSERT (alignof (f32) == MINALIGN (32)); + +ASSERT (!__builtin_has_attribute (f, aligned)); +ASSERT (__builtin_has_attribute (f_, aligned)); +ASSERT (!__builtin_has_attribute (f0, aligned)); + +ASSERT (!HAS_ALIGN (f_, MAXALIGN)); + +ASSERT (HAS_ALIGN (f1, 1)); +ASSERT (!HAS_ALIGN (f1, 2)); + +ASSERT (!HAS_ALIGN (f2, 1)); +ASSERT (HAS_ALIGN (f2, 2)); +ASSERT (!HAS_ALIGN (f2, 4)); + +ASSERT (!HAS_ALIGN (f4, 2)); +ASSERT (HAS_ALIGN (f4, 4)); +ASSERT (!HAS_ALIGN (f4, 8)); + +ASSERT (!HAS_ALIGN (f8, 4)); +ASSERT (HAS_ALIGN (f8, 8)); +ASSERT (!HAS_ALIGN (f8, 16)); + +ASSERT (!HAS_ALIGN (f16, 8)); +ASSERT (HAS_ALIGN (f16, 16)); +ASSERT (!HAS_ALIGN (f16, 32)); + +ASSERT (!HAS_ALIGN (f32, 16)); +ASSERT (HAS_ALIGN (f32, 32)); +ASSERT (!HAS_ALIGN (f32, 64)); -- 2.7.4