diff options
author | Martin Sebor <msebor@redhat.com> | 2016-12-14 17:23:16 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2016-12-14 10:23:16 -0700 |
commit | 474da67ef9ec3658e4da9deb5373353532b2a840 (patch) | |
tree | 9216700dc546aef48d9bff1a0ab2203160ce0f8e /gcc/testsuite | |
parent | b4ba0852099ad28a533327ac25e8337910be28e8 (diff) | |
download | gcc-474da67ef9ec3658e4da9deb5373353532b2a840.zip gcc-474da67ef9ec3658e4da9deb5373353532b2a840.tar.gz gcc-474da67ef9ec3658e4da9deb5373353532b2a840.tar.bz2 |
PR c/78673 - sprintf missing attribute nonnull on destination argument
PR c/78673 - sprintf missing attribute nonnull on destination argument
PR c/17308 - nonnull attribute not as useful as it could be
gcc/ChangeLog:
PR c/17308
* builtin-attrs.def (ATTR_NONNULL_1_1, ATTR_NONNULL_1_2): Defined.
(ATTR_NONNULL_1_3, ATTR_NONNULL_1_4, ATTR_NONNULL_1_5): Same.
(ATTR_NOTHROW_NONNULL_1_1, ATTR_NOTHROW_NONNULL_1_2): Same.
(ATTR_NOTHROW_NONNULL_1_3, ATTR_NOTHROW_NONNULL_1_4): Same.
(ATTR_NOTHROW_NONNULL_1_5): Same.
(ATTR_NONNULL_1_FORMAT_PRINTF_1_2): Same.
(ATTR_NONNULL_1_FORMAT_PRINTF_2_0): Same.
(ATTR_NONNULL_1_FORMAT_PRINTF_2_3): Same.
(ATTR_NONNULL_1_FORMAT_PRINTF_3_0): Same.
(ATTR_NONNULL_1_FORMAT_PRINTF_3_4): Same.
(ATTR_NONNULL_1_FORMAT_PRINTF_4_0): Same.
(ATTR_NONNULL_1_FORMAT_PRINTF_4_5): Same.
* builtins.c (validate_arg): Add argument. Treat null pointers
passed to nonnull arguments as invalid.
(validate_arglist): Same.
* builtins.def (fprintf, fprintf_unlocked): Add nonnull attribute.
(printf, printf_unlocked, sprintf. vfprintf, vsprintf): Same.
(__sprintf_chk, __vsprintf_chk, __fprintf_chk, __vfprintf_chk): Same.
* calls.c (get_nonnull_ags, maybe_warn_null_arg): New functions.
(initialize_argument_information): Diagnose null pointers passed to
arguments declared nonnull.
* calls.h (get_nonnull_args): Declared.
gcc/c-family/ChangeLog:
PR c/17308
* c-common.c (check_nonnull_arg): Disable when optimization
is enabled.
gcc/testsuite/ChangeLog:
PR c/17308
* gcc.dg/builtins-nonnull.c: New test.
* gcc.dg/nonnull-4.c: New test.
From-SVN: r243661
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtins-nonnull.c | 239 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/nonnull-4.c | 79 |
3 files changed, 324 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 47a98ac..64d7839 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-12-14 Martin Sebor <msebor@redhat.com> + + PR c/17308 + * gcc.dg/builtins-nonnull.c: New test. + * gcc.dg/nonnull-4.c: New test. + 2016-12-14 Nathan Sidwell <nathan@acm.org> PR c++/78701 diff --git a/gcc/testsuite/gcc.dg/builtins-nonnull.c b/gcc/testsuite/gcc.dg/builtins-nonnull.c new file mode 100644 index 0000000..fa9eaf2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtins-nonnull.c @@ -0,0 +1,239 @@ +/* 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; + +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. */ + bzero (null (), 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" } */ +} + +#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" } */ +} diff --git a/gcc/testsuite/gcc.dg/nonnull-4.c b/gcc/testsuite/gcc.dg/nonnull-4.c new file mode 100644 index 0000000..577a04c --- /dev/null +++ b/gcc/testsuite/gcc.dg/nonnull-4.c @@ -0,0 +1,79 @@ +/* PR c/78673 - sprintf missing attribute nonnull on destination argument + Test to verify that calls to user-defined functions declared with + the "nonnull" function attribute are diagnosed. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wnonnull" } */ + +#define N(...) __attribute__ ((nonnull (__VA_ARGS__))) + +void N (1) f1_1 (void*); + +void N (1) f2_1 (void*, void*); +void N (1) N (2) f2_1_2 (void*, void*); + +void N (1) N (3) f3_1_3 (void*, void*, void*); + +void N (1, 2) N (4) g4_1_2_4 (void*, void*, void*, void*); +void N (1, 3) N (4) g4_1_3_4 (void*, void*, void*, void*); +void N (2, 3, 4) g4_2_3_4 (void*, void*, void*, void*); + +void N () g4_all (void*, void*, void*, void*); + +void N (1, 3, 5, 7, 11, 13) +g16_1_3_5_7_11_13 (void*, void*, void*, void*, + void*, void*, void*, void*, + void*, void*, void*, void*, + void*, void*, void*, void*); + +void* null (void) { return 0; } + +void test (void) +{ + void *p0 = null (); + void *px = &px; + + f1_1 (p0); /* { dg-warning "argument 1 null where non-null expected " } */ + f1_1 (px); + + f2_1 (p0, px); /* { dg-warning "argument 1 null" } */ + f2_1 (px, p0); + f2_1 (p0, p0); /* { dg-warning "argument 1 null" } */ + + f2_1_2 (p0, px); /* { dg-warning "argument 1 null" } */ + f2_1_2 (px, p0); /* { dg-warning "argument 2 null" } */ + f2_1_2 (p0, p0); /* { dg-warning "argument 1 null" } */ + /* { dg-warning "argument 2 null" "argument 2" { target *-*-* } .-1 } */ + + f3_1_3 (p0, px, px); /* { dg-warning "argument 1 null" } */ + f3_1_3 (px, p0, px); + f3_1_3 (px, px, p0); /* { dg-warning "argument 3 null" } */ + f3_1_3 (p0, p0, px); /* { dg-warning "argument 1 null" } */ + f3_1_3 (px, p0, p0); /* { dg-warning "argument 3 null" } */ + f3_1_3 (p0, p0, p0); /* { dg-warning "argument 1 null" } */ + /* { dg-warning "argument 3 null" "argument 3" { target *-*-* } .-1 } */ + + g4_1_2_4 (p0, px, px, px); /* { dg-warning "argument 1 null" } */ + g4_1_2_4 (px, p0, px, px); /* { dg-warning "argument 2 null" } */ + g4_1_2_4 (px, px, p0, px); + g4_1_2_4 (px, px, px, p0); /* { dg-warning "argument 4 null" } */ + + g4_1_3_4 (p0, px, px, px); /* { dg-warning "argument 1 null" } */ + g4_1_3_4 (px, p0, px, px); + g4_1_3_4 (px, px, p0, px); /* { dg-warning "argument 3 null" } */ + g4_1_3_4 (px, px, px, p0); /* { dg-warning "argument 4 null" } */ + + g4_2_3_4 (p0, px, px, px); + g4_2_3_4 (px, p0, px, px); /* { dg-warning "argument 2 null" } */ + g4_2_3_4 (px, px, p0, px); /* { dg-warning "argument 3 null" } */ + g4_2_3_4 (px, px, px, p0); /* { dg-warning "argument 4 null" } */ + + g4_all (p0, px, px, px); /* { dg-warning "argument 1 null" } */ + g4_all (px, p0, px, px); /* { dg-warning "argument 2 null" } */ + g4_all (px, px, p0, px); /* { dg-warning "argument 3 null" } */ + g4_all (px, px, px, p0); /* { dg-warning "argument 4 null" } */ + + g16_1_3_5_7_11_13 (px, px, px, px, px, px, px, px, + px, px, px, px, px, px, px, px); + + g16_1_3_5_7_11_13 (px, p0, px, p0, px, p0, px, p0, p0, p0, px, p0, p0, p0, p0, p0); /* { dg-warning "argument 13 null" } */ +} |