diff options
author | David Malcolm <dmalcolm@redhat.com> | 2023-01-13 17:51:26 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2023-01-13 17:51:26 -0500 |
commit | ccd4df81aa6537c3c935b026905f6e2fd839654e (patch) | |
tree | fd538d541afa3f3394c81a32b0e1865942372d57 /gcc/analyzer/region-model.h | |
parent | 6071e495e5802a8949d2b02df6aa31a5f40f2af9 (diff) | |
download | gcc-ccd4df81aa6537c3c935b026905f6e2fd839654e.zip gcc-ccd4df81aa6537c3c935b026905f6e2fd839654e.tar.gz gcc-ccd4df81aa6537c3c935b026905f6e2fd839654e.tar.bz2 |
analyzer: add heuristics for switch on enum type [PR105273]
Assume that switch on an enum doesn't follow an implicit default
skipping all cases when all enum values are covered by cases.
Fixes various false positives from -Wanalyzer-use-of-uninitialized-value
such as this one seen in Doom:
p_maputl.c: In function 'P_BoxOnLineSide':
p_maputl.c:151:8: warning: use of uninitialized value 'p1' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
151 | if (p1 == p2)
| ^
'P_BoxOnLineSide': events 1-5
|
| 115 | int p1;
| | ^~
| | |
| | (1) region created on stack here
| | (2) capacity: 4 bytes
|......
| 118 | switch (ld->slopetype)
| | ~~~~~~
| | |
| | (3) following 'default:' branch...
|......
| 151 | if (p1 == p2)
| | ~
| | |
| | (4) ...to here
| | (5) use of uninitialized value 'p1' here
|
where "ld->slopetype" is a "slopetype_t" enum, and for every value of
that enum the switch has a case that initializes "p1".
gcc/analyzer/ChangeLog:
PR analyzer/105273
* region-model.cc (has_nondefault_case_for_value_p): New.
(has_nondefault_cases_for_all_enum_values_p): New.
(region_model::apply_constraints_for_gswitch): Skip
implicitly-created "default" when switching on an enum
and all enum values have non-default cases.
(rejected_default_case::dump_to_pp): New.
* region-model.h (region_model_context::possibly_tainted_p): New
decl.
(class rejected_default_case): New.
* sm-taint.cc (region_model_context::possibly_tainted_p): New.
* supergraph.cc (switch_cfg_superedge::dump_label_to_pp): Dump
when implicitly_created_default_p.
(switch_cfg_superedge::implicitly_created_default_p): New.
* supergraph.h
(switch_cfg_superedge::implicitly_created_default_p): New decl.
gcc/testsuite/ChangeLog:
PR analyzer/105273
* gcc.dg/analyzer/switch-enum-1.c: New test.
* gcc.dg/analyzer/switch-enum-2.c: New test.
* gcc.dg/analyzer/switch-enum-pr105273-git-vreportf-2.c: New test.
* gcc.dg/analyzer/switch-enum-taint-1.c: New test.
* gcc.dg/analyzer/switch-wrong-enum.c: New test.
* gcc.dg/analyzer/torture/switch-enum-pr105273-doom-p_floor.c: New
test.
* gcc.dg/analyzer/torture/switch-enum-pr105273-doom-p_maputl.c:
New test.
* gcc.dg/analyzer/torture/switch-enum-pr105273-git-vreportf-1.c:
New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/region-model.h')
-rw-r--r-- | gcc/analyzer/region-model.h | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index e8767e5..4e1a5c6 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -703,6 +703,8 @@ class region_model_context return get_state_map_by_name ("taint", out_smap, out_sm, out_sm_idx, NULL); } + bool possibly_tainted_p (const svalue *sval); + /* Get the current statement, if any. */ virtual const gimple *get_stmt () const = 0; }; @@ -1010,6 +1012,16 @@ public: tree m_rhs; }; +class rejected_default_case : public rejected_constraint +{ +public: + rejected_default_case (const region_model &model) + : rejected_constraint (model) + {} + + void dump_to_pp (pretty_printer *pp) const final override; +}; + class rejected_ranges_constraint : public rejected_constraint { public: |