diff gcc/testsuite/gcc.dg/builtin-object-size-16.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-16.c	Fri Oct 27 22:46:09 2017 +0900
@@ -0,0 +1,205 @@
+/* PR 71831 - __builtin_object_size poor results with no optimization
+   Verify that even without optimization __builtin_object_size returns
+   a meaningful result for a subset of simple expressins.  In cases
+   where the result could not easily be made to match the one obtained
+   with optimization the built-in was made to fail instead.  */
+/* { dg-do run } */
+/* { dg-options "-O0" } */
+
+static int nfails;
+
+#define TEST_FAILURE(line, obj, type, expect, result)		\
+  __builtin_printf ("FAIL: line %i: __builtin_object_size("	\
+		    #obj ", %i) == %zu, got %zu\n",		\
+		    line, type, expect, result), ++nfails
+
+#define bos(obj, type) __builtin_object_size (obj, type)
+#define size(obj, n) ((size_t)n == X ? sizeof *obj : (size_t)n)
+
+#define test(expect, type, obj)						\
+  do {									\
+    if (bos (obj, type)	!= size (obj, expect))				\
+      TEST_FAILURE (__LINE__, obj, type, size (obj, expect), bos (obj, type)); \
+  } while (0)
+
+#define T(r0, r1, r2, r3, obj)			\
+  do {						\
+    test (r0, 0, obj);				\
+    test (r1, 1, obj);				\
+    test (r2, 2, obj);				\
+    test (r3, 3, obj);				\
+  } while (0)
+
+/* For convenience.  Substitute for 'sizeof object' in test cases where
+   the size can vary from target to target.  */
+#define X  (size_t)0xdeadbeef
+
+/* __builtin_object_size checking results are inconsistent for equivalent
+   expressions (see bug 71831).  To avoid having duplicate the inconsistency
+   at -O0 the built-in simply fails.  The results hardcoded in this test
+   are those obtained with optimization (for easy comparison) but without
+   optimization the macros below turn them into expected failures .  */
+#if __OPTIMIZE__
+#  define F0(n)    n
+#  define F1(n)    n
+#  define F2(n)    n
+#  define F3(n)    n
+#else
+#  define F0(n)   -1
+#  define F1(n)   -1
+#  define F2(n)    0
+#  define F3(n)    0
+#endif
+
+typedef __SIZE_TYPE__ size_t;
+
+extern char ax[];
+char ax2[];               /* { dg-warning "assumed to have one element" } */
+
+extern char a0[0];
+static char a1[1];
+static char a2[2];
+static char a9[9];
+
+#if __SIZEOF_SHORT__ == 4
+extern short ia0[0];
+static short ia1[1];
+static short ia9[9];
+#elif __SIZEOF_INT__ == 4
+extern int ia0[0];
+static int ia1[1];
+static int ia9[9];
+#elif __SIZEOF_LONG__ == 4
+extern long ia0[0];
+static long ia1[1];
+static long ia9[9];
+#endif
+
+static char a2x2[2][2];
+static char a3x5[3][5];
+
+struct Sx { char n, a[]; } sx;
+struct S0 { char n, a[0]; } s0;
+struct S1 { char n, a[1]; } s1;
+struct S2 { char n, a[2]; } s2;
+struct S9 { char n, a[9]; } s9;
+
+struct S2x2 { char n, a[2][2]; } s2x2;
+struct S3x5 { char n, a[3][5]; } s3x5;
+
+static __attribute__ ((noclone, noinline)) void
+test_arrays ()
+{
+  T (    -1,      -1,       0,       0,   ax);
+
+  T (     0,       0,       0,       0,   a0);
+  T (     1,       1,       1,       1,   ax2);
+
+  T (     1,       1,       1,       1,   a1);
+  T (     2,       2,       2,       2,   a2);
+  T (     9,       9,       9,       9,   a9);
+
+  T (     0,       0,       0,       0,   a0);
+  T (     1,       1,       1,       1,   ax2);
+
+  T (     0,       0,       0,       0,   ia0);
+  T (     4,       4,       4,       4,   ia1);
+  T (    36,      36,      36,      36,   ia9);
+
+  /* Not all results for multidimensional arrays make sense (see
+     bug 77293).  The expected results below simply reflect those
+     obtained at -O2 (modulo the known limitations at -O1).  */
+  T (     4,       4,       4,       4,   a2x2);
+  T (     4,       4,       4,       4,   &a2x2[0]);
+  T (     4,       2,       4,       2,   &a2x2[0][0]);
+  T (     0,  F1  (0),      0,       0,   &a2x2 + 1);
+  T (     2,  F1 ( 2),      2,  F3 ( 2),  &a2x2[0] + 1);
+  T (     3,  F1 ( 1),      3,  F3 ( 3),  &a2x2[0][0] + 1);
+
+  T (    15,      15,      15,      15,   a3x5);
+  T (    15,       5,      15,       5,   &a3x5[0][0] + 0);
+  T (    14,  F1 ( 4),     14,  F3 (14),  &a3x5[0][0] + 1);
+
+  T (     1,       1,       1,       1,   a1 + 0);
+  T (     0,  F1  (0),      0,       0,   a1 + 1);
+  T (     0,  F1 ( 0),      0,       0,   &a1 + 1);
+  /* In the following the offset is out of bounds which makes
+     the expression undefined.  Still, verify that the returned
+     size is zero (and not some large number).  */
+  T (     0,  F1  (0),      0,       0,   a1 + 2);
+
+  T (     2,       2,       2,       2,   a2 + 0);
+  T (     1,  F1 ( 1),      1, F3 ( 1),   a2 + 1);
+  T (     0,  F1 ( 0),      0,       0,   a2 + 2);
+}
+
+static __attribute__ ((noclone, noinline)) void
+test_structs (struct Sx *psx, struct S0 *ps0, struct S1 *ps1, struct S9 *ps9)
+{
+  /* The expected size of a declared object with a flexible array member
+     is sizeof sx in all __builtin_object_size types.  */
+  T (     X,       X,       X,       X,   &sx);
+
+  /* The expected size of an unknown object with a flexible array member
+     is unknown in all __builtin_object_size types.  */
+  T (    -1,      -1,       0,       0,   psx);
+
+  /* The expected size of a flexible array member of a declared object
+     is zero.  */
+  T (     0,       0,       0,       0,   sx.a);
+
+  /* The expected size of a flexible array member of an unknown object
+     is unknown.  */
+  T (    -1,      -1,       0,       0,   psx->a);
+
+  /* The expected size of a declared object with a zero-length array member
+     is sizeof sx in all __builtin_object_size types.  */
+  T (     X,       X,       X,       X,   &s0);
+
+  /* The expected size of an unknown object with a zero-length array member
+     is unknown in all __builtin_object_size types.  */
+  T (    -1,      -1,       0,       0,   ps0);
+
+  /* The expected size of a zero-length array member of a declared object
+     is zero.  */
+  T (     0,       0,       0,       0,   s0.a);
+
+  /* The expected size of a zero-length array member of an unknown object
+     is unknown.  */
+  T (    -1,      -1,       0,       0,   ps0->a);
+
+  T (     X,       X,       X,       X,   &s1);
+  T (     1,       1,       1,       1,   s1.a);
+  T (     0,  F1 (0),       0,       0,   s1.a + 1);
+
+  /* GCC treats arrays of all sizes that are the last member of a struct
+     as flexible array members.  */
+  T (    -1,      -1,       0,       0,   ps1);
+  T (    -1,      -1,       0,       0,   ps1->a);
+  T (    -1,      -1,       0,       0,   ps1->a + 1);
+
+  T (     X,       X,       X,       X,   &s9);
+  T (     9,       9,       9,       9,   s9.a);
+  T (     9,       9,       9,       9,   s9.a + 0);
+  T (     8,  F1 ( 8),      8, F3 (  8),  s9.a + 1);
+  T (     7,  F1 ( 7),      7, F3 (  7),  s9.a + 2);
+  T (     0,  F1 ( 0),      0, F3 (  0),  s9.a + 9);
+
+  /* The following make little sense but see bug 77301.  */
+  T (    -1,      -1,       0,       0,   ps9);
+  T (    -1,      -1,       0,       0,   ps9->a);
+  T (    -1,      -1,       0,       0,   ps9->a + 1);
+}
+
+int
+main()
+{
+  test_arrays ();
+
+  test_structs (&sx, &s0, &s1, &s9);
+
+  if (nfails)
+    __builtin_abort ();
+
+  return 0;
+}