Viewing file: strlenopt-84.c (2.49 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* 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" } { dg-require-effective-target alloca } */
#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); }
|