aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/sm-malloc.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-03-20 18:33:11 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2024-03-20 18:33:11 -0400
commit9093f275e0a3430e4517e782e7f5419d403113f7 (patch)
treec3811ae2a97d4dcf5f05877bebebb91cc650393c /gcc/analyzer/sm-malloc.cc
parentf10c18df9c02dc518360426c021971838e0012d2 (diff)
downloadgcc-9093f275e0a3430e4517e782e7f5419d403113f7.zip
gcc-9093f275e0a3430e4517e782e7f5419d403113f7.tar.gz
gcc-9093f275e0a3430e4517e782e7f5419d403113f7.tar.bz2
analyzer: fix -Wanalyzer-deref-before-check false positive seen in loop header macro [PR109251]
gcc/analyzer/ChangeLog: PR analyzer/109251 * sm-malloc.cc (deref_before_check::emit): Reject cases where the check is in a loop header within a macro expansion. (deref_before_check::loop_header_p): New. gcc/testsuite/ChangeLog: PR analyzer/109251 * c-c++-common/analyzer/deref-before-check-pr109251-1.c: New test. * c-c++-common/analyzer/deref-before-check-pr109251-2.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/sm-malloc.cc')
-rw-r--r--gcc/analyzer/sm-malloc.cc30
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index a518816..4e11d6d 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -1563,6 +1563,21 @@ public:
if (linemap_location_from_macro_definition_p (line_table, check_loc))
return false;
+ /* Reject warning if the check is in a loop header within a
+ macro expansion. This rejects cases like:
+ | deref of x;
+ | [...snip...]
+ | FOR_EACH(x) {
+ | [...snip...]
+ | }
+ where the FOR_EACH macro tests for non-nullness of x, since
+ the user is hoping to encapsulate the details of iteration
+ in the macro, and the extra check on the first iteration
+ would just be noise if we reported it. */
+ if (loop_header_p (m_check_enode->get_point ())
+ && linemap_location_from_macro_expansion_p (line_table, check_loc))
+ return false;
+
/* Reject if m_deref_expr is sufficiently different from m_arg
for cases where the dereference is spelled differently from
the check, which is probably two different ways to get the
@@ -1618,6 +1633,21 @@ public:
}
private:
+ static bool loop_header_p (const program_point &point)
+ {
+ const supernode *snode = point.get_supernode ();
+ if (!snode)
+ return false;
+ for (auto &in_edge : snode->m_preds)
+ {
+ if (const cfg_superedge *cfg_in_edge
+ = in_edge->dyn_cast_cfg_superedge ())
+ if (cfg_in_edge->back_edge_p ())
+ return true;
+ }
+ return false;
+ }
+
static bool sufficiently_similar_p (tree expr_a, tree expr_b)
{
pretty_printer *pp_a = global_dc->printer->clone ();