diff gcc/testsuite/gcc.dg/strlenopt-84.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/gcc.dg/strlenopt-84.c	Thu Feb 13 11:34:05 2020 +0900
@@ -0,0 +1,135 @@
+/* PR tree-optimization/83821 - local aggregate initialization defeats
+   strlen optimization
+   Verify that stores that overwrite an interior nul are correctly
+   reflected in strlen results.
+   { dg-do run }
+   { dg-options "-O2 -Wall" } */
+
+#define false (0 == 1)
+#define true (0 == 0)
+#define assert(e)							\
+  ((e) ? (void)0 : (__builtin_printf ("assertion failed on line %i\n",	\
+				      __LINE__), __builtin_abort ()))
+
+#define ATTR(...) __attribute__ ((__VA_ARGS__))
+
+static inline int ATTR (always_inline)
+assign_and_get_length (char *p, _Bool clear)
+{
+  p[0] = 'a';
+
+  if (clear)
+    p[1] = 0;
+
+  p[2] = 'c';
+
+  if (clear)
+    p[3] = 0;
+
+  p[1] = 'b';
+
+  return __builtin_strlen (p);
+}
+
+ATTR (noipa) void array_get_length (void)
+{
+  char a[4];
+  unsigned n = assign_and_get_length (a, true);
+  assert (n == 3);
+}
+
+ATTR (noipa) void clear_array_get_length (void)
+{
+  char a[4] = { };
+  unsigned n = assign_and_get_length (a, false);
+  assert (n == 3);
+}
+
+ATTR (noipa) void calloc_get_length (void)
+{
+  char *p = __builtin_calloc (5, 1);
+  unsigned n = assign_and_get_length (p, false);
+  assert (n == 3);
+}
+
+ATTR (noipa) void malloc_get_length (void)
+{
+  char *p = __builtin_malloc (5);
+  unsigned n = assign_and_get_length (p, true);
+  assert (n == 3);
+}
+
+ATTR (noipa) void vla_get_length (int n)
+{
+  char a[n];
+  unsigned len = assign_and_get_length (a, true);
+  assert (len == 3);
+}
+
+
+static inline void ATTR (always_inline)
+assign_and_test_length (char *p, _Bool clear)
+{
+  p[0] = 'a';
+
+  if (clear)
+    p[1] = 0;
+
+  p[2] = 'c';
+
+  if (clear)
+    p[3] = 0;
+
+  unsigned n0 =  __builtin_strlen (p);
+
+  p[1] = 'b';
+
+  unsigned n1 =  __builtin_strlen (p);
+  assert (n0 != n1);
+}
+
+ATTR (noipa) void array_test_length (void)
+{
+  char a[4];
+  assign_and_test_length (a, true);
+}
+
+ATTR (noipa) void clear_array_test_length (void)
+{
+  char a[4] = { };
+  assign_and_test_length (a, false);
+}
+
+ATTR (noipa) void calloc_test_length (void)
+{
+  char *p = __builtin_calloc (5, 1);
+  assign_and_test_length (p, false);
+}
+
+ATTR (noipa) void malloc_test_length (void)
+{
+  char *p = __builtin_malloc (5);
+  assign_and_test_length (p, true);
+}
+
+ATTR (noipa) void vla_test_length (int n)
+{
+  char a[n];
+  assign_and_test_length (a, true);
+}
+
+int main (void)
+{
+  array_get_length ();
+  clear_array_get_length ();
+  calloc_get_length ();
+  malloc_get_length ();
+  vla_get_length (4);
+
+  array_test_length ();
+  clear_array_test_length ();
+  calloc_test_length ();
+  malloc_test_length ();
+  vla_test_length (4);
+}
+