diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-08-08 06:22:56 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-08-08 15:36:51 +0200 |
commit | a060d243f8dc17e399641b0dfebeb4faf5eb7580 (patch) | |
tree | 6a086284707033c6dd75a3c1d4b3baa32025ed26 | |
parent | aa198d93e6a28bd8c040d82a00a9256d97d61516 (diff) | |
download | sparse-a060d243f8dc17e399641b0dfebeb4faf5eb7580.tar.gz |
wstring: add support for checking size in string initializer
A warning is given for string initializers if the LHS array
is not large enough to contains the string. But this check
doesn't knowns about wide strings.
Fix this by selecting the correct char type and use this type
for the size calculations.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | evaluate.c | 6 | ||||
-rw-r--r-- | validation/init-wstring.c | 41 | ||||
-rw-r--r-- | validation/init_cstring.c | 2 |
3 files changed, 47 insertions, 2 deletions
@@ -2841,10 +2841,12 @@ String: *p = *e; type = evaluate_expression(p); if (ctype->bit_size != -1) { - if (ctype->bit_size + bits_in_char < type->bit_size) + struct symbol *char_type = e->wide ? wchar_ctype : &char_ctype; + unsigned int size_with_null = ctype->bit_size + char_type->bit_size; + if (size_with_null < type->bit_size) warning(e->pos, "too long initializer-string for array of char"); - else if (Winit_cstring && ctype->bit_size + bits_in_char == type->bit_size) { + else if (Winit_cstring && size_with_null == type->bit_size) { warning(e->pos, "too long initializer-string for array of char(no space for nul char)"); } diff --git a/validation/init-wstring.c b/validation/init-wstring.c new file mode 100644 index 00000000..846b6e2c --- /dev/null +++ b/validation/init-wstring.c @@ -0,0 +1,41 @@ +static const __WCHAR_TYPE__ ok0[] = L"abc"; +_Static_assert(sizeof(ok0) == 4 * sizeof(__WCHAR_TYPE__)); +static const __WCHAR_TYPE__ ok1[] = (L"abc"); +_Static_assert(sizeof(ok1) == 4 * sizeof(__WCHAR_TYPE__)); +static const __WCHAR_TYPE__ ok2[] = { L"abc" }; +_Static_assert(sizeof(ok2) == 4 * sizeof(__WCHAR_TYPE__)); + +static const __WCHAR_TYPE__ ok3[4] = L"abc"; +_Static_assert(sizeof(ok3) == 4 * sizeof(__WCHAR_TYPE__)); +static const __WCHAR_TYPE__ ok4[4] = (L"abc"); +_Static_assert(sizeof(ok4) == 4 * sizeof(__WCHAR_TYPE__)); +static const __WCHAR_TYPE__ ok5[4] = { (L"abc") }; +_Static_assert(sizeof(ok5) == 4 * sizeof(__WCHAR_TYPE__)); + +static const __WCHAR_TYPE__ ok6[7] = L"abc"; +_Static_assert(sizeof(ok6) == 7 * sizeof(__WCHAR_TYPE__)); +static const __WCHAR_TYPE__ ok7[7] = (L"abc"); +_Static_assert(sizeof(ok7) == 7 * sizeof(__WCHAR_TYPE__)); +static const __WCHAR_TYPE__ ok8[7] = { (L"abc") }; +_Static_assert(sizeof(ok8) == 7 * sizeof(__WCHAR_TYPE__)); + +static const __WCHAR_TYPE__ *ptr[] = { L"abc" }; +_Static_assert(sizeof(ptr) == sizeof(void *)); + +static struct s { + const __WCHAR_TYPE__ str[4]; +} str = { L"xyz" }; + +static const __WCHAR_TYPE__ ko3[3] = L"abc"; +static const __WCHAR_TYPE__ ko2[2] = L"abc"; + +/* + * check-name: init-wstring + * check-command: sparse -Winit-cstring $file + * check-known-to-fail + * + * check-error-start +init-wstring.c:29:38: warning: too long initializer-string for array of char(no space for nul char) +init-wstring.c:30:38: warning: too long initializer-string for array of char + * check-error-end + */ diff --git a/validation/init_cstring.c b/validation/init_cstring.c index 00eca20a..bac814e4 100644 --- a/validation/init_cstring.c +++ b/validation/init_cstring.c @@ -1,11 +1,13 @@ static struct alpha { char a[2]; } x = { .a = "ab" }; +static const char str[2] = "abc"; /* * check-name: -Winit-cstring option * * check-command: sparse -Winit-cstring $file * check-error-start init_cstring.c:3:14: warning: too long initializer-string for array of char(no space for nul char) +init_cstring.c:4:28: warning: too long initializer-string for array of char * check-error-end */ |