/* PR middle-end/10138 - warn for uninitialized arrays passed as const* arguments Verify that passing pointers to uninitialized objects to const arguments to built-ins is diagnosed where expected. { dg-do compile } { dg-options "-O -Wall -ftrivial-auto-var-init=zero" } { dg-require-effective-target alloca } */ typedef __SIZE_TYPE__ size_t; void* alloca (size_t); void* malloc (size_t); void* realloc (void*, size_t); void* memcpy (void*, const void*, size_t); char* strcpy (char*, const char*); size_t strlen (const char*); void sink (void*); void nowarn_array_memcpy (void *d, unsigned n) { int a[2]; /* Diagnose this? */ memcpy (d, a, n /* Non-constant to avoid folding into MEM_REF. */); } void nowarn_array_plus_cst_memcpy (void *d, unsigned n) { int a[3]; /* Diagnose this? */ memcpy (d, a + 1, n); } void nowarn_array_plus_var_memcpy (void *d, unsigned n, int i) { int a[4]; /* Diagnose this? */ memcpy (d, a + i, n); } void nowarn_array_assign_memcpy (char *d, unsigned n) { int a[3]; a[1] = 3; memcpy (d, a, n); } void nowarn_array_init_memcpy (char *d, unsigned n) { int a[4] = { 0 }; memcpy (d, a, n); } void nowarn_array_compound_memcpy (void *d, unsigned n) { memcpy (d, (int[2]){ 0 }, n); } void nowarn_struct_assign_memcpy (void *d, unsigned n) { struct S { int a, b, c, d; } s; s.b = 1; s.d = 2; memcpy (d, &s, n); } void nowarn_array_init_strcpy (char *d[], unsigned n) { char a[8] = "012"; strcpy (d[0], a); strcpy (d[1], a + 1); strcpy (d[1], a + 2); strcpy (d[1], a + 3); strcpy (d[1], a + 4); strcpy (d[1], a + 5); strcpy (d[1], a + 6); strcpy (d[1], a + 7); } void nowarn_array_assign_strcpy (char *d[], unsigned n) { char a[8]; a[0] = '0'; a[1] = '1'; a[2] = '2'; a[3] = '\0'; strcpy (d[0], a); strcpy (d[1], a + 1); strcpy (d[1], a + 2); strcpy (d[1], a + 3); } void warn_array_plus_cst_strcpy (char *d, unsigned n) { char a[8]; a[0] = '1'; a[1] = '2'; a[2] = '3'; a[3] = '\0'; strcpy (d, a + 4); // { dg-warning "\\\[-Wuninitialized" } strcpy (d, a + 5); // { dg-warning "\\\[-Wuninitialized" } strcpy (d, a + 6); // { dg-warning "\\\[-Wuninitialized" } strcpy (d, a + 7); // { dg-warning "\\\[-Wuninitialized" } } void nowarn_array_plus_var_strcpy (char *d, int i) { char a[8]; a[0] = '1'; a[1] = '2'; a[2] = '3'; a[3] = '\0'; strcpy (d, a + i); } size_t nowarn_array_assign_strlen (const char *s) { char a[8]; a[0] = s[0]; a[1] = s[1]; a[2] = s[2]; a[3] = s[3]; size_t n = 0; n += strlen (a); n += strlen (a + 1); n += strlen (a + 2); n += strlen (a + 3); return n; } size_t warn_array_plus_cst_strlen (const char *s) { char a[8]; a[0] = s[0]; a[1] = s[1]; a[2] = s[2]; a[3] = s[3]; return strlen (a + 4); // { dg-warning "\\\[-Wuninitialized" } } size_t nowarn_array_plus_var_strlen (const char *s, int i) { char a[8]; a[0] = s[0]; a[1] = s[1]; a[2] = s[2]; a[3] = s[3]; return strlen (a + i); } size_t nowarn_alloca_assign_strlen (int i) { char *p = (char*)alloca (8); p[i] = '\0'; return strlen (p); } size_t nowarn_alloca_escape_strlen (int i) { char *p = (char*)alloca (8); sink (p); return strlen (p); } size_t warn_alloca_strlen (void) { char *p = (char*)alloca (8); return strlen (p); // { dg-warning "\\\[-Wuninitialized" } } size_t nowarn_malloc_assign_strlen (int i) { char *p = (char*)malloc (8); p[i] = '\0'; return strlen (p); } size_t nowarn_malloc_escape_strlen (int i) { char *p = (char*)malloc (8); sink (p); return strlen (p); } size_t warn_malloc_strlen (void) { char *p = (char*)malloc (8); return strlen (p); // { dg-warning "\\\[-Wuninitialized" } } size_t nowarn_realloc_strlen (void *p) { char *q = (char*)realloc (p, 8); return strlen (q); } size_t nowarn_vla_assign_strlen (int n, int i) { char vla[n]; vla[i] = '\0'; return strlen (vla); } size_t nowarn_vla_strcpy_strlen (int n, const char *s, int i) { char vla[n]; strcpy (vla, s); return strlen (vla + i); } size_t nowarn_vla_escape_strlen (int n, int i) { char vla[n]; sink (vla); return strlen (vla); } size_t warn_vla_strlen (unsigned n) { char vla[n]; return strlen (vla); // { dg-warning "\\\[-Wuninitialized" } }