diff gcc/testsuite/c-c++-common/builtin-has-attribute-2.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/testsuite/c-c++-common/builtin-has-attribute-2.c	Thu Feb 13 11:34:05 2020 +0900
@@ -0,0 +1,206 @@
+/* Verify __builtin_has_attribute return value for types.
+   { dg-do compile }
+   { dg-options "-Wall -ftrack-macro-expansion=0" }
+   { dg-options "-Wall -Wno-narrowing -Wno-unused-local-typedefs -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)]
+
+struct ATTR (packed) Packed { char c; int i; };
+
+void fvoid (void);
+struct Packed fpacked (void);
+
+union OrdinaryUnion { void *p; int i; };
+union ATTR (transparent_union) TransparentUnion { void *p; int i; };
+
+/* Exercise __builtin_has_attribute with the first argument that
+   is a type.  */
+
+void test_type (int n)
+{
+  /* Verify both forms of the attribute spelling.  Unlike the attribute
+     keyword that can be spelled three ways (with either leading or
+     trailing underscores, or with both), attribute names can only be
+     spelled two ways.  */
+  A (0, int, aligned);
+  A (0, int, __aligned__);
+
+  A (0, int, aligned (1));
+  A (0, int, aligned (2));
+  A (0, int[1], aligned);
+  A (0, int[1], aligned (2));
+  A (0, int[n], aligned);
+  A (0, int[n], aligned (4));
+
+  /* Again, verify both forms of the attribute spelling.  */
+  A (1, ATTR (aligned) char, aligned);
+  A (1, ATTR (aligned (2)) short, aligned);
+  A (1, ATTR (aligned (4)) int, __aligned__);
+
+  A (0, int ATTR (aligned (4)), aligned (2));
+  A (0, int ATTR (aligned (2)), aligned (4));
+  /* 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)); */
+  A (0, int ATTR (aligned (4), aligned (2)), aligned (8));
+
+  A (1, int ATTR (aligned (8)), aligned (1 + 7));
+
+  enum { eight = 8 };
+  A (1, int ATTR (aligned (8)), aligned (eight));
+  A (1, int ATTR (aligned (eight)), aligned (1 + 7));
+
+  struct NotPacked { char c; int i; };
+  A (0, struct NotPacked, packed);
+  A (1, struct Packed, packed);
+
+  /* Exercise types returned from a function.  */
+  A (0, fvoid (), packed);
+  A (1, fpacked (), packed);
+
+  struct ATTR (aligned (2), packed) Aligned2Packed { char c; int i; };
+  A (1, struct Aligned2Packed, aligned);
+  A (1, struct Aligned2Packed, aligned (2));
+  A (0, struct Aligned2Packed, aligned (4));
+  A (1, struct Aligned2Packed, packed);
+
+  A (0, int, may_alias);
+  A (1, ATTR (may_alias) int, may_alias);
+
+  A (0, char, warn_if_not_aligned (1));
+  A (0, char, warn_if_not_aligned (2));
+
+  A (1, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned);
+  A (0, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned (1));
+  A (1, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned (2));
+  A (0, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned (4));
+
+  A (0, union OrdinaryUnion, transparent_union);
+
+  A (1, union TransparentUnion, transparent_union);
+  A (1, const union TransparentUnion, transparent_union);
+}
+
+/* Exercise __builtin_has_attribute with the first argument that
+   is a typedef.  */
+
+void test_typedef (int n)
+{
+  typedef char A1[1];
+  A (0, A1, aligned);
+  A (0, A1, aligned (1));
+  A (0, A1, aligned (2));
+
+  typedef char An[n];
+  A (0, An, aligned);
+  A (0, An, aligned (1));
+  A (0, An, aligned (2));
+
+  typedef ATTR (aligned (8)) short AI8;
+  A (1, AI8, aligned);
+  A (0, AI8, aligned (4));
+  A (1, AI8, aligned (8));
+  A (0, AI8, aligned (16));
+
+  A (1, const AI8, aligned);
+  A (1, const volatile AI8, aligned);
+
+  typedef ATTR (aligned (2), aligned (8), aligned (16)) int AI16;
+  A (1, AI16, aligned);
+  A (0, AI16, aligned (1));
+  A (0, AI16, aligned (2));
+  A (0, AI16, aligned (4));
+  A (0, AI16, aligned (8));
+  A (1, AI16, aligned (16));
+  A (0, AI16, aligned (32));
+
+  typedef const AI16 CAI16;
+  A (1, CAI16, aligned);
+  A (0, CAI16, aligned (1));
+  A (1, CAI16, aligned (16));
+
+  typedef int I;
+  A (0, I, may_alias);
+  A (0, AI8, may_alias);
+
+  typedef ATTR (may_alias) int MAI;
+  A (1, MAI, may_alias);
+
+  typedef ATTR (aligned (4), may_alias) char A4MAC;
+  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));
+  A (0, A4MAC, aligned (8));
+  A (1, A4MAC, may_alias);
+
+  typedef ATTR (may_alias, aligned (8)) char A8MAC;
+  A (1, A8MAC, aligned);
+  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));
+  A (1, A8MAC, aligned (8));
+  A (0, A8MAC, aligned (16));
+  A (1, A8MAC, may_alias);
+
+  typedef ATTR (may_alias) const AI8 CMAI8;
+  A (1, CMAI8, aligned);
+  A (1, CMAI8, may_alias);
+  A (0, CMAI8, aligned (4));
+  A (1, CMAI8, aligned (8));
+
+  typedef void Fnull (void*, void*, void*);
+  A (0, Fnull, nonnull);
+  A (0, Fnull, nonnull (1));
+  A (0, Fnull, nonnull (2));
+  A (0, Fnull, nonnull (3));
+
+  typedef ATTR (nonnull) Fnull Fnonnull;
+  A (1, Fnonnull, nonnull);
+  A (1, Fnonnull, nonnull (1));
+  A (1, Fnonnull, nonnull (2));
+  A (1, Fnonnull, nonnull (3));
+
+  typedef ATTR (nonnull (2)) void Fnonnull_2 (void*, void*, void*);
+  A (0, Fnonnull_2, nonnull);
+  A (0, Fnonnull_2, nonnull (1));
+  A (1, Fnonnull_2, nonnull (2));
+  A (0, Fnonnull_2, nonnull (3));
+
+  typedef ATTR (nonnull (1), nonnull (2), nonnull (3))
+    void Fnonnull_1_2_3 (void*, void*, void*);
+
+  /* The following fails because  the built-in doesn't recognize that
+     a single nonnull with no arguments is the same as one nonnull for
+     each function parameter.  Disable the testing for now.
+     A (1, Fnonnull_1_2_3, nonnull);
+  */
+  A (1, Fnonnull_1_2_3, nonnull (1));
+  A (1, Fnonnull_1_2_3, nonnull (2));
+  A (1, Fnonnull_1_2_3, nonnull (3));
+
+  typedef void Freturns (void);
+  A (0, Fnull, noreturn);
+  A (0, Freturns, noreturn);
+
+  typedef ATTR (warn_if_not_aligned (8)) char CWA8;
+  A (0, CWA8, warn_if_not_aligned (2));
+  A (0, CWA8, warn_if_not_aligned (4));
+  A (1, CWA8, warn_if_not_aligned (8));
+  A (0, CWA8, warn_if_not_aligned (16));
+
+  typedef union OrdinaryUnion OrdUnion;
+  A (0, OrdUnion, transparent_union);
+
+  /* The attribute is ignored on typedefs but GCC fails to diagnose
+     it (see bug ).  */
+  typedef union ATTR (transparent_union)
+    OrdinaryUnion TransUnion;   /* { dg-warning "\\\[-Wattributes" "pr87578" { xfail { ! { c++ } } } } */
+  A (0, TransUnion, transparent_union);
+}