| 1 | // RUN: %clang_cc1 -Wmemset-transposed-args -verify %s |
| 2 | // RUN: %clang_cc1 -xc++ -Wmemset-transposed-args -verify %s |
| 3 | |
| 4 | #define memset(...) __builtin_memset(__VA_ARGS__) |
| 5 | #define bzero(x,y) __builtin_memset(x, 0, y) |
| 6 | #define real_bzero(x,y) __builtin_bzero(x,y) |
| 7 | |
| 8 | int array[10]; |
| 9 | int *ptr; |
| 10 | |
| 11 | int main() { |
| 12 | memset(array, sizeof(array), 0); // expected-warning{{'size' argument to memset is '0'; did you mean to transpose the last two arguments?}} expected-note{{parenthesize the third argument to silence}} |
| 13 | memset(array, sizeof(array), 0xff); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}} expected-warning{{'memset' will always overflow; destination buffer has size 40, but size argument is 255}} |
| 14 | memset(ptr, sizeof(ptr), 0); // expected-warning{{'size' argument to memset is '0'; did you mean to transpose the last two arguments?}} expected-note{{parenthesize the third argument to silence}} |
| 15 | memset(ptr, sizeof(*ptr) * 10, 1); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}} |
| 16 | memset(ptr, 10 * sizeof(int *), 1); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}} |
| 17 | memset(ptr, 10 * sizeof(int *) + 10, 0xff); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}} |
| 18 | memset(ptr, sizeof(char) * sizeof(int *), 0xff); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}} |
| 19 | memset(array, sizeof(array), sizeof(array)); // Uh... fine I guess. |
| 20 | memset(array, 0, sizeof(array)); |
| 21 | memset(ptr, 0, sizeof(int *) * 10); |
| 22 | memset(array, (int)sizeof(array), (0)); // no warning |
| 23 | memset(array, (int)sizeof(array), 32); // no warning |
| 24 | memset(array, 32, (0)); // no warning |
| 25 | memset(array, 0, 0); // no warning |
| 26 | |
| 27 | bzero(ptr, 0); // expected-warning{{'size' argument to bzero is '0'}} expected-note{{parenthesize the second argument to silence}} |
| 28 | real_bzero(ptr, 0); // expected-warning{{'size' argument to bzero is '0'}} expected-note{{parenthesize the second argument to silence}} |
| 29 | } |
| 30 | |
| 31 | void macros() { |
| 32 | #define ZERO 0 |
| 33 | int array[10]; |
| 34 | memset(array, 0xff, ZERO); // no warning |
| 35 | // Still emit a diagnostic for memsetting a sizeof expression: |
| 36 | memset(array, sizeof(array), ZERO); // expected-warning{{'sizeof'}} expected-note{{cast}} |
| 37 | bzero(array, ZERO); // no warning |
| 38 | real_bzero(array, ZERO); // no warning |
| 39 | #define NESTED_DONT_DIAG \ |
| 40 | memset(array, 0xff, ZERO); \ |
| 41 | real_bzero(array, ZERO); |
| 42 | |
| 43 | NESTED_DONT_DIAG; |
| 44 | |
| 45 | #define NESTED_DO_DIAG \ |
| 46 | memset(array, 0xff, 0); \ |
| 47 | real_bzero(array, 0) |
| 48 | |
| 49 | NESTED_DO_DIAG; // expected-warning{{'size' argument to memset}} expected-warning{{'size' argument to bzero}} expected-note2{{parenthesize}} |
| 50 | |
| 51 | #define FN_MACRO(p) \ |
| 52 | memset(array, 0xff, p) |
| 53 | |
| 54 | FN_MACRO(ZERO); |
| 55 | FN_MACRO(0); // FIXME: should we diagnose this? |
| 56 | |
| 57 | __builtin_memset(array, 0, ZERO); // no warning |
| 58 | __builtin_bzero(array, ZERO); |
| 59 | __builtin_memset(array, 1, 0); // expected-warning{{'size' argument to memset}} // expected-note{{parenthesize}} |
| 60 | __builtin_bzero(array, 0); // expected-warning{{'size' argument to bzero}} // expected-note{{parenthesize}} |
| 61 | } |
| 62 | |