Mercurial > hg > CbC > CbC_gcc
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); +} +