/* PR c/17308 - nonnull attribute not as useful as it could be PR c/78673 - sprintf missing attribute nonnull on destination argument { dg-do "compile" } { dg-additional-options "-O2 -Wnonnull -ftrack-macro-expansion=0 -std=c99" } */ #define va_list __builtin_va_list typedef struct FILE FILE; static char* null (void) { return 0; } void sink (int, ...); #define T(arg) sink (0, arg) #define bzero __builtin_bzero #define memcpy __builtin_memcpy #define memmove __builtin_memmove #define mempcpy __builtin_mempcpy #define memset __builtin_memset void test_memfuncs (void *s, unsigned n) { /* Bzero is not declared attribute nonnull (maybe it should be?) but it's transformed into a call to memset() which is. */ bzero (null (), n); /* { dg-warning "argument 1 null where non-null expected" } */ T (memcpy (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (memcpy (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (memmove (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (memmove (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (mempcpy (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (mempcpy (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (memset (null (), 0, n)); /* { dg-warning "argument 1 null where non-null expected" } */ } #undef memcpy #undef memmove #undef mempcpy #undef memset #define memcpy(d, s, n) __builtin___memcpy_chk (d, s, n, n) #define memmove(d, s, n) __builtin___memmove_chk (d, s, n, n) #define mempcpy(d, s, n) __builtin___mempcpy_chk (d, s, n, n) #define memset(d, x, n) __builtin___memset_chk (d, x, n, n) void test_memfuncs_chk (void *s, unsigned n) { T (memcpy (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (memcpy (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (memmove (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (memmove (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (mempcpy (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (mempcpy (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (memset (null (), 0, n)); /* { dg-warning "argument 1 null where non-null expected" } */ } #define strcat __builtin_strcat #define strchr __builtin_strchr #define stpcpy __builtin_stpcpy #define stpncpy __builtin_stpncpy #define strcpy __builtin_strcpy #define strncpy __builtin_strncpy #define strlen __builtin_strlen #define strncat __builtin_strncat #define strstr __builtin_strstr void test_strfuncs (char *s, unsigned n) { T (strcat (null (), s)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strcat (s, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ T (strchr (null (), 'x')); /* { dg-warning "argument 1 null where non-null expected" } */ T (stpcpy (null (), s)); /* { dg-warning "argument 1 null where non-null expected" } */ T (stpcpy (s, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ T (stpncpy (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (stpncpy (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (strcpy (null (), s)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strcpy (s, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ T (strncpy (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strncpy (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (strlen (null ())); /* { dg-warning "argument 1 null where non-null expected" } */ T (strncat (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (strncat (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strstr (null (), s)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strstr (s, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ } #undef strcat #undef stpcpy #undef stpncpy #undef strcpy #undef strncpy #undef strncat #define strcat(d, s) __builtin___strcat_chk (d, s, n) #define stpcpy(d, s) __builtin___stpcpy_chk (d, s, n) #define stpncpy(d, s, n) __builtin___stpncpy_chk (d, s, n, n) #define strcpy(d, s) __builtin___strcpy_chk (d, s, n) #define strncpy(d, s, n) __builtin___strncpy_chk (d, s, n, n) #define strncat(d, s, n) __builtin___strncat_chk (d, s, n, n) void test_strfuncs_chk (char *s, unsigned n) { T (strcat (null (), s)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strcat (s, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ T (strchr (null (), 'x')); /* { dg-warning "argument 1 null where non-null expected" } */ T (stpcpy (null (), s)); /* { dg-warning "argument 1 null where non-null expected" } */ T (stpcpy (s, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ T (stpncpy (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (stpncpy (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (strcpy (null (), s)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strcpy (s, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ T (strncpy (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ T (strncpy (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (strncat (s, null (), n)); /* { dg-warning "argument 2 null where non-null expected" } */ T (strncat (null (), s, n)); /* { dg-warning "argument 1 null where non-null expected" } */ } #define fprintf __builtin_fprintf #define fprintf_unlocked __builtin_fprintf_unlocked #define vfprintf __builtin_vfprintf #define printf __builtin_printf #define printf_unlocked __builtin_printf_unlocked #define vprintf __builtin_vprintf #define sprintf __builtin_sprintf #define snprintf __builtin_snprintf #define vsprintf __builtin_vsprintf #define vsnprintf __builtin_vsnprintf void test_stdio_funcs (FILE *f, char *d, unsigned n, va_list va) { T (fprintf (null (), "%i", 0)); /* { dg-warning "argument 1 null where non-null expected" } */ T (fprintf (f, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ T (fprintf_unlocked (null (), "%i", 0)); /* { dg-warning "argument 1 null where non-null expected" } */ T (fprintf_unlocked (f, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ T (vfprintf (null (), "%i", va));/* { dg-warning "argument 1 null where non-null expected" } */ T (vfprintf (f, null (), va)); /* { dg-warning "argument 2 null where non-null expected" } */ T (vprintf (null (), va)); /* { dg-warning "argument 1 null where non-null expected" } */ T (printf (null ())); /* { dg-warning "argument 1 null where non-null expected" } */ T (printf_unlocked (null ())); /* { dg-warning "argument 1 null where non-null expected" } */ T (vprintf (null (), va)); /* { dg-warning "argument 1 null where non-null expected" } */ T (sprintf (null (), "%i", 0)); /* { dg-warning "argument 1 null where non-null expected" } */ T (sprintf (d, null ())); /* { dg-warning "argument 2 null where non-null expected" } */ T (snprintf (null (), n, "%i", 0)); T (snprintf (d, n, null ())); /* { dg-warning "argument 3 null where non-null expected" } */ T (vsprintf (null (), "%i", va)); /* { dg-warning "argument 1 null where non-null expected" } */ T (vsprintf (d, null (), va)); /* { dg-warning "argument 2 null where non-null expected" } */ T (vsnprintf (null (), n, "%i", va)); T (vsnprintf (d, n, null (), va)); /* { dg-warning "argument 3 null where non-null expected" } */ } #undef fprintf #undef fprintf_unlocked #undef vfprintf #undef printf #undef printf_unlocked #undef vprintf #undef sprintf #undef snprintf #undef vsprintf #undef vsnprintf #define fprintf(f, fmt, ...) \ __builtin___fprintf_chk (f, 0, fmt, __VA_ARGS__) #define vfprintf(f, fmt, va) \ __builtin___vfprintf_chk (f, 0, fmt, va) #define printf(fmt, ...) \ __builtin___printf_chk (0, fmt, __VA_ARGS__) #define vprintf(fmt, va) \ __builtin___vprintf_chk (0, fmt, va) #define sprintf(d, fmt, ... ) \ __builtin___sprintf_chk (d, 0, n, fmt, __VA_ARGS__) #define snprintf(d, n, fmt, ...) \ __builtin___snprintf_chk (d, n, 0, n, fmt, __VA_ARGS__) #define vsprintf(d, fmt, va) \ __builtin___vsprintf_chk (d, 0, n, fmt, va) #define vsnprintf(d, n, fmt, va) \ __builtin___vsnprintf_chk (d, n, 0, n, fmt, va) void test_stdio_funcs_chk (FILE *f, char *d, const char *fmt, unsigned n, va_list va) { T (fprintf (null (), "%i", 0)); /* { dg-warning "argument 1 null where non-null expected" } */ T (fprintf (f, null (), 0)); /* { dg-warning "argument 3 null where non-null expected" } */ T (vfprintf (null (), "%i", va));/* { dg-warning "argument 1 null where non-null expected" } */ T (vfprintf (f, null (), va)); /* { dg-warning "argument 3 null where non-null expected" } */ T (vprintf (null (), va)); /* { dg-warning "argument 2 null where non-null expected" } */ T (printf (null (), 0)); /* { dg-warning "argument 2 null where non-null expected" } */ T (vprintf (null (), va)); /* { dg-warning "argument 2 null where non-null expected" } */ T (sprintf (null (), "%i", 0)); /* { dg-warning "argument 1 null where non-null expected" } */ T (sprintf (d, null (), 0)); /* { dg-warning "argument 4 null where non-null expected" } */ T (snprintf (null (), n, "%i", 0)); T (snprintf (d, n, null (), 0)); /* { dg-warning "argument 5 null where non-null expected" } */ T (vsprintf (null (), "%i", va)); /* { dg-warning "argument 1 null where non-null expected" } */ T (vsprintf (d, null (), va)); /* { dg-warning "argument 4 null where non-null expected" } */ T (vsnprintf (null (), n, "%i", va)); T (vsnprintf (d, n, null (), va)); /* { dg-warning "argument 5 null where non-null expected" } */ }