diff options
author | David Malcolm <dmalcolm@redhat.com> | 2021-04-05 10:48:01 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2021-04-05 10:48:01 -0400 |
commit | 69b66ff02353a87585329bb3cf4ac20d6dee1b16 (patch) | |
tree | d65789a51f9c7a14f4b6fcf0f13a157d8a680bd8 /gcc/analyzer | |
parent | bd89b8fe9efbdf0a95d827553d1a84fd3cefaa16 (diff) | |
download | gcc-69b66ff02353a87585329bb3cf4ac20d6dee1b16.zip gcc-69b66ff02353a87585329bb3cf4ac20d6dee1b16.tar.gz gcc-69b66ff02353a87585329bb3cf4ac20d6dee1b16.tar.bz2 |
analyzer: fix apparent hang with -fanalyzer-verbosity=0 [PR analyzer/99886]
The analyzer appeared to enter an infinite loop on malloc-1.c
when -fanalyzer-verbosity=0 was used. In fact, it was slowly
counting from 0 to 0xffffffff.
Root cause is looping up to effectively ((unsigned)0) - 1 in
diagnostic_manager::consolidate_conditions when there are no events
in the path.
Fixed by the following, which uses signed integers when subtracting
from path->num_events () when simplifying checker_paths.
gcc/analyzer/ChangeLog:
PR analyzer/99886
* diagnostic-manager.cc
(diagnostic_manager::prune_interproc_events): Use signed integers
when subtracting one from path->num_events ().
(diagnostic_manager::consolidate_conditions): Likewise. Convert
next_idx to a signed int.
gcc/testsuite/ChangeLog:
PR analyzer/99886
* gcc.dg/analyzer/pr99886.c: New test.
Diffstat (limited to 'gcc/analyzer')
-rw-r--r-- | gcc/analyzer/diagnostic-manager.cc | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index 9ec3e89..443ff05 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -2081,7 +2081,7 @@ diagnostic_manager::prune_interproc_events (checker_path *path) const do { changed = false; - int idx = path->num_events () - 1; + int idx = (signed)path->num_events () - 1; while (idx >= 0) { /* Prune [..., call, function-entry, return, ...] triples. */ @@ -2200,7 +2200,9 @@ diagnostic_manager::consolidate_conditions (checker_path *path) const if (flag_analyzer_verbose_edges) return; - for (unsigned start_idx = 0; start_idx < path->num_events () - 1; start_idx++) + for (int start_idx = 0; + start_idx < (signed)path->num_events () - 1; + start_idx++) { if (path->cfg_edge_pair_at_p (start_idx)) { @@ -2231,7 +2233,7 @@ diagnostic_manager::consolidate_conditions (checker_path *path) const [start_idx, next_idx) where all apart from the final event are on the same line, and all are either TRUE or FALSE edges, matching the initial. */ - unsigned next_idx = start_idx + 2; + int next_idx = start_idx + 2; while (path->cfg_edge_pair_at_p (next_idx) && same_line_as_p (start_exp_loc, path, next_idx)) { |