diff options
author | David Malcolm <dmalcolm@redhat.com> | 2023-08-21 21:13:19 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2023-08-21 21:13:19 -0400 |
commit | fe97f09a0caeff2a22cc41b26bf08692bff8686d (patch) | |
tree | cfbe083ec82f0a543007c4f67109d0f28326643d /gcc/analyzer/store.h | |
parent | 1e7b0a5d7a45dc5932992d36e1375582d61269e4 (diff) | |
download | gcc-fe97f09a0caeff2a22cc41b26bf08692bff8686d.zip gcc-fe97f09a0caeff2a22cc41b26bf08692bff8686d.tar.gz gcc-fe97f09a0caeff2a22cc41b26bf08692bff8686d.tar.bz2 |
analyzer: replace -Wanalyzer-unterminated-string with scan_for_null_terminator [PR105899]
In r14-3169-g325f9e88802daa I added check_for_null_terminated_string_arg
to -fanalyzer, calling it in various places, with a sole check for
unterminated string constants, adding -Wanalyzer-unterminated-string for
this case.
This patch adds region_model::scan_for_null_terminator, which simulates
scanning memory for a zero byte, complaining about uninitiliazed bytes
and out-of-range accesses seen before any zero byte is seen.
This more flexible approach catches the issues we saw before with
-Wanalyzer-unterminated-string, and also catches uninitialized runs
of bytes, and I believe will be a better way to build checking of C
string operations in the analyzer.
Given that the patch makes -Wanalyzer-unterminated-string redundant
and that this option was only in trunk for 10 days and has no known
users, the patch simply removes the option without a compatibility
fallback.
The patch uses custom events and notes to provide context on where
the issues are coming from. For example, given:
null-terminated-strings-1.c: In function ‘test_partially_initialized’:
null-terminated-strings-1.c:71:3: warning: use of uninitialized value ‘buf[1]’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
71 | __analyzer_get_strlen (buf);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
‘test_partially_initialized’: events 1-3
|
| 69 | char buf[16];
| | ^~~
| | |
| | (1) region created on stack here
| 70 | buf[0] = 'a';
| 71 | __analyzer_get_strlen (buf);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (2) while looking for null terminator for argument 1 (‘&buf’) of ‘__analyzer_get_strlen’...
| | (3) use of uninitialized value ‘buf[1]’ here
|
analyzer-decls.h:59:22: note: argument 1 of ‘__analyzer_get_strlen’ must be a pointer to a null-terminated string
59 | extern __SIZE_TYPE__ __analyzer_get_strlen (const char *ptr);
| ^~~~~~~~~~~~~~~~~~~~~
gcc/analyzer/ChangeLog:
PR analyzer/105899
* analyzer.opt (Wanalyzer-unterminated-string): Delete.
* call-details.cc
(call_details::check_for_null_terminated_string_arg): Convert
return type from void to const svalue *. Add param "out_sval".
* call-details.h
(call_details::check_for_null_terminated_string_arg): Likewise.
* kf-analyzer.cc (kf_analyzer_get_strlen::impl_call_pre): Wire up
to result of check_for_null_terminated_string_arg.
* region-model.cc (get_strlen): Delete.
(class unterminated_string_arg): Delete.
(struct fragment): New.
(class iterable_cluster): New.
(region_model::get_store_bytes): New.
(get_tree_for_byte_offset): New.
(region_model::scan_for_null_terminator): New.
(region_model::check_for_null_terminated_string_arg): Convert
return type from void to const svalue *. Add param "out_sval".
Reimplement in terms of scan_for_null_terminator, dropping the
special-case for -Wanalyzer-unterminated-string.
* region-model.h (region_model::get_store_bytes): New decl.
(region_model::scan_for_null_terminator): New decl.
(region_model::check_for_null_terminated_string_arg): Convert
return type from void to const svalue *. Add param "out_sval".
* store.cc (concrete_binding::get_byte_range): New.
* store.h (concrete_binding::get_byte_range): New decl.
(store_manager::get_concrete_binding): New overload.
gcc/ChangeLog:
PR analyzer/105899
* doc/invoke.texi: Remove -Wanalyzer-unterminated-string.
gcc/testsuite/ChangeLog:
PR analyzer/105899
* gcc.dg/analyzer/error-1.c: Update expected results to reflect
reimplementation of unterminated string detection. Add test
coverage for uninitialized buffers.
* gcc.dg/analyzer/null-terminated-strings-1.c: Likewise.
* gcc.dg/analyzer/putenv-1.c: Likewise.
* gcc.dg/analyzer/strchr-1.c: Likewise.
* gcc.dg/analyzer/strcpy-1.c: Likewise.
* gcc.dg/analyzer/strdup-1.c: Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/store.h')
-rw-r--r-- | gcc/analyzer/store.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/gcc/analyzer/store.h b/gcc/analyzer/store.h index af6cc7e..cf10fa3 100644 --- a/gcc/analyzer/store.h +++ b/gcc/analyzer/store.h @@ -399,6 +399,7 @@ public: { return this; } const bit_range &get_bit_range () const { return m_bit_range; } + bool get_byte_range (byte_range *out) const; bit_offset_t get_start_bit_offset () const { @@ -855,6 +856,12 @@ public: return get_concrete_binding (bits.get_start_bit_offset (), bits.m_size_in_bits); } + const concrete_binding * + get_concrete_binding (const byte_range &bytes) + { + bit_range bits = bytes.as_bit_range (); + return get_concrete_binding (bits); + } const symbolic_binding * get_symbolic_binding (const region *region); |