137 lines
2.5 KiB
C
137 lines
2.5 KiB
C
/* 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);
|
|
}
|
|
|