blob: c5b5f0c6b65c2d7e7e577997afb465a6b9f4369c [file] [log] [blame]
/* PR tree-optimization/104119 - unexpected -Wformat-overflow after strlen
in ILP32 since Ranger integration
Verify that unlike -Wformat-overflow the sprintf optimization doesn't
assume the length of a string isn't bounded by the size of the array
member it's stored in.
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
typedef __SIZE_TYPE__ size_t;
void* memcpy (void*, const void*, size_t);
int snprintf (char*, size_t, const char*, ...);
char* strcpy (char*, const char*);
size_t strlen (const char*);
extern void keep_call_on_line (int);
extern void elim_call_on_line (int);
void sink (void*, ...);
struct __attribute__ ((packed)) S
{
char a4[4], b4[4], ax[];
};
extern struct S es;
void test_extern_decl_memcpy (void)
{
struct S *p = &es;
/* Set strlen (P->A4) to [3, PTRDIFF - 2]. */
memcpy (p->a4, "123", 3);
int i = snprintf (0, 0, "%s", p->a4);
if (i > 4)
keep_call_on_line (__LINE__);
}
void test_extern_decl_strcpy_3 (void)
{
struct S *p = &es;
/* Set strlen (P->A4) to 3. */
strcpy (p->a4, "123");
int i = snprintf (0, 0, "%s", p->a4);
if (i > 4)
elim_call_on_line (__LINE__);
}
void test_extern_decl_strcpy_X (const char *s)
{
struct S *p = &es;
/* Set strlen (P->A4) to [0, PTRDIFF_MAX - 2]. */
strcpy (p->a4, s);
int i = snprintf (0, 0, "%s", p->a4);
if (i > 4)
keep_call_on_line (__LINE__);
}
size_t test_extern_decl_strlen (void)
{
struct S *p = &es;
/* Set strlen (P->A4) to [0, PTRDIFF - 2]. */
size_t n = strlen (p->a4);
int i = snprintf (0, 0, "%s", p->a4);
if (i > 4)
keep_call_on_line (__LINE__);
return n;
}
static struct S ss;
/* Store and read SS to prevent optimizers from assuming it's unchanged. */
extern void set_ss (struct S *p)
{
if (ss.a4[(unsigned char)*p->a4])
__builtin_memcpy (&ss, p, sizeof ss);
}
void test_static_decl_memcpy (void)
{
struct S *p = &ss;
/* Set strlen (P->A4) to [3, PTRDIFF - 2]. */
memcpy (p->a4, "123", 3);
int i = snprintf (0, 0, "%s", p->a4);
if (i > 4)
keep_call_on_line (__LINE__);
}
void test_static_decl_strcpy_3 (void)
{
struct S *p = &ss;
/* Set strlen (P->A4) to 3. */
strcpy (p->a4, "123");
int i = snprintf (0, 0, "%s", p->a4);
if (i > 4)
elim_call_on_line (__LINE__);
}
void test_static_decl_strcpy_X (const char *s)
{
struct S *p = &ss;
/* Set strlen (P->A4) to [0, PTRDIFF_MAX - 2]. */
strcpy (p->a4, s);
int i = snprintf (0, 0, "%s", p->a4);
if (i > 4)
keep_call_on_line (__LINE__);
}
size_t test_static_decl_strlen (void)
{
struct S *p = &ss;
/* Set strlen (P->A4) to [0, PTRDIFF - 2]. */
size_t n = strlen (p->a4);
int i = snprintf (0, 0, "%s", p->a4);
if (i > 4)
keep_call_on_line (__LINE__);
return n;
}
/* { dg-final { scan-tree-dump-times "keep_call_on_line" 6 "optimized" } }
{ dg-final { scan-tree-dump-not "elim_call_on_line" "optimized" } } */