aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer
AgeCommit message (Collapse)AuthorFilesLines
2023-03-23Daily bump.GCC Administrator1-0/+11
2023-03-22analyzer: fix false +ves from -Wanalyzer-deref-before-check due to inlining ↵David Malcolm3-4/+50
[PR109239] The patch has this effect on my integration tests of -fanalyzer: Comparison: GOOD: 129 (17.70% -> 17.92%) BAD: 600 -> 591 (-9) which is purely due to improvements to -Wanalyzer-deref-before-check on the Linux kernel: -Wanalyzer-deref-before-check: GOOD: 1 (4.55% -> 7.69%) BAD: 21 -> 12 (-9) Known false positives: 16 -> 10 (-6) linux-5.10.162: 7 -> 1 (-6) Suspected false positives: 3 -> 0 (-3) linux-5.10.162: 3 -> 0 (-3) gcc/analyzer/ChangeLog: PR analyzer/109239 * program-point.cc: Include "analyzer/inlining-iterator.h". (program_point::effectively_intraprocedural_p): New function. * program-point.h (program_point::effectively_intraprocedural_p): New decl. * sm-malloc.cc (deref_before_check::emit): Use it when rejecting interprocedural cases, so that we reject interprocedural cases that have become intraprocedural due to inlining. gcc/testsuite/ChangeLog: PR analyzer/109239 * gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-03-19Daily bump.GCC Administrator1-0/+11
2023-03-18analyzer: fix ICE on certain longjmp calls [PR109094]David Malcolm2-4/+14
PR analyzer/109094 reports an ICE in the analyzer seen on qemu's target/i386/tcg/translate.c The issue turned out to be that when handling a longjmp, the code to pop the frames was generating an svalue for the result_decl of any popped frame that had a non-void return type (and discarding it) leading to "uninit" poisoned_svalue_diagnostic instances being saved since the result_decl is only set by the greturn stmt. Later, when checking the feasibility of the path to these diagnostics, m_check_expr was evaluated in the context of the frame of the longjmp, leading to an attempt to evaluate the result_decl of each intervening frames whilst in the context of the topmost frame, leading to an assertion failure in frame_region::get_region_for_local here: 919 case RESULT_DECL: 920 gcc_assert (DECL_CONTEXT (expr) == m_fun->decl); 921 break; This patch updates the analyzer's longjmp implementation so that it doesn't attempt to generate svalues for the result_decls when popping frames, fixing the assertion failure (and presumably fixing "uninit" false positives in a release build). gcc/analyzer/ChangeLog: PR analyzer/109094 * region-model.cc (region_model::on_longjmp): Pass false for new "eval_return_svalue" param of pop_frame. (region_model::pop_frame): Add new "eval_return_svalue" param and use it to suppress the call to get_rvalue on the result when needed by on_longjmp. * region-model.h (region_model::pop_frame): Add new "eval_return_svalue" param. gcc/testsuite/ChangeLog: PR analyzer/109094 * gcc.dg/analyzer/setjmp-pr109094.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-03-11Daily bump.GCC Administrator1-0/+48
2023-03-10analyzer: fix leak false +ve seen in haproxy's cfgparse.c [PR109059]David Malcolm3-16/+69
If a bound region gets overwritten with UNKNOWN due to being possibly-aliased during a write, that could have been the only region keeping its value live, in which case we could falsely report a leak. This is hidden somewhat by the "uncertainty" mechanism for cases where the write happens in the same stmt as the last reference to the value goes away, but not in the general case, which occurs in PR analyzer/109059, which falsely complains about a leak whilst haproxy updates a doubly-linked list. The whole "uncertainty_t" class seems broken to me now; I think we need to track (in the store) what values could have escaped to the external part of the program. We do this to some extent for pointers by tracking the region as escaped, though we're failing to do this for this case: even though there could still be other pointers to the region, eventually they go away; we want to capture the fact that the external part of the state is still keeping it live. Also, this doesn't work for non-pointer svalues, such as for detecting file-descriptor leaks. As both a workaround and a step towards eventually removing "class uncertainty_t" this patch updates the "mark_region_as_unknown" code called by possibly-aliased set_value so that when old values are removed, any base region pointed to them is marked as escaped, fixing the leak false positive. The patch has this effect on my integration tests of -fanalyzer: Comparison: GOOD: 129 (19.20% -> 20.22%) BAD: 543 -> 509 (-34) where there's a big improvement in -Wanalyzer-malloc-leak: -Wanalyzer-malloc-leak: GOOD: 61 (45.19% -> 54.95%) BAD: 74 -> 50 (-24) Known false positives: 25 -> 2 (-23) haproxy-2.7.1: 24 -> 1 (-23) Suspected false positives: 49 -> 48 (-1) coreutils-9.1: 32 -> 31 (-1) and some churn in the other warnings: -Wanalyzer-use-of-uninitialized-value: GOOD: 0 BAD: 81 -> 80 (-1) -Wanalyzer-file-leak: GOOD: 0 BAD: 10 -> 11 (+1) -Wanalyzer-out-of-bounds: GOOD: 0 BAD: 24 -> 22 (-2) gcc/analyzer/ChangeLog: PR analyzer/109059 * region-model.cc (region_model::mark_region_as_unknown): Gather a set of maybe-live svalues and call on_maybe_live_values with it. * store.cc (binding_map::remove_overlapping_bindings): Add new "maybe_live_values" param; add any removed svalues to it. (binding_cluster::clobber_region): Add NULL as new param of remove_overlapping_bindings. (binding_cluster::mark_region_as_unknown): Add "maybe_live_values" param and pass it to remove_overlapping_bindings. (binding_cluster::maybe_get_compound_binding): Add NULL for new param of binding_map::remove_overlapping_bindings. (binding_cluster::remove_overlapping_bindings): Add "maybe_live_values" param and pass to binding_map::remove_overlapping_bindings. (store::set_value): Capture a set of maybe-live svalues, and call on_maybe_live_values with it. (store::on_maybe_live_values): New. (store::mark_region_as_unknown): Add "maybe_live_values" param and pass it to binding_cluster::mark_region_as_unknown. (store::remove_overlapping_bindings): Pass NULL for new param of binding_cluster::remove_overlapping_bindings. * store.h (binding_map::remove_overlapping_bindings): Add "maybe_live_values" param. (binding_cluster::mark_region_as_unknown): Likewise. (binding_cluster::remove_overlapping_bindings): Likewise. (store::mark_region_as_unknown): Likewise. (store::on_maybe_live_values): New decl. gcc/testsuite/ChangeLog: PR analyzer/109059 * gcc.dg/analyzer/flex-with-call-summaries.c: Remove xfail. * gcc.dg/analyzer/leak-pr109059-1.c: New test. * gcc.dg/analyzer/leak-pr109059-2.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-03-10analyzer: fix deref-before-check false +ves seen in haproxy [PR108475,PR109060]David Malcolm1-37/+44
Integration testing showed various false positives from -Wanalyzer-deref-before-check where the expression that's dereferenced is different from the one that's checked, but the diagnostic is emitted because they both evaluate to the same symbolic value. This patch rejects such warnings, unless we have tree expressions for both and that both tree expressions are "spelled the same way" i.e. would be printed to the same user-facing string. gcc/analyzer/ChangeLog: PR analyzer/108475 PR analyzer/109060 * sm-malloc.cc (deref_before_check::deref_before_check): Initialize new field m_deref_expr. Assert that arg is non-NULL. (deref_before_check::emit): Reject cases where the spelling of the thing that was dereferenced differs from that of what is checked, or if the dereference expression was not found. Remove code to handle NULL m_arg. (deref_before_check::describe_state_change): Remove code to handle NULL m_arg. (deref_before_check::describe_final_event): Likewise. (deref_before_check::sufficiently_similar_p): New. (deref_before_check::m_deref_expr): New field. (malloc_state_machine::maybe_complain_about_deref_before_check): Don't warn if the diag_ptr is NULL. gcc/testsuite/ChangeLog: PR analyzer/108475 PR analyzer/109060 * gcc.dg/analyzer/deref-before-check-pr108475-1.c: New test. * gcc.dg/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c: New test. * gcc.dg/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-03-04Daily bump.GCC Administrator1-0/+5
2023-03-03analyzer: provide placeholder implementation of sprintfDavid Malcolm1-0/+29
Previously, the analyzer lacked a known_function implementation of sprintf, and thus would handle calls to sprintf with the "anything could happen" fallback. Whilst working on PR analyzer/107565 I noticed that this was preventing a lot of genuine memory leaks from being reported for Doom; fixing thusly. Integration testing of the effect of the patch shows a big increase in true positives due to the case mentioned in Doom, and one new false positive (in pcre2), which I'm tracking as PR analyzer/109014. Comparison: GOOD: 67 -> 123 (+56); 10.91% -> 18.33% BAD: 547 -> 548 (+1) where the affected warnings/projects are: -Wanalyzer-malloc-leak: GOOD: 0 -> 56 (+56); 0.00% -> 41.48% BAD: 79 True positives: 0 -> 56 (+56) (all in Doom) -Wanalyzer-use-of-uninitialized-value: GOOD: 0; 0.00% BAD: 80 -> 81 (+1) False positives: pcre2-10.42: 0 -> 1 (+1) gcc/analyzer/ChangeLog: * kf.cc (class kf_sprintf): New. (register_known_functions): Register it. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/doom-d_main-IdentifyVersion.c: New test. * gcc.dg/analyzer/sprintf-1.c: New test. * gcc.dg/analyzer/sprintf-concat.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-03-03Daily bump.GCC Administrator1-0/+10
2023-03-02analyzer: fix uninit false +ves reading from DECL_HARD_REGISTER [PR108968]David Malcolm1-1/+8
gcc/analyzer/ChangeLog: PR analyzer/108968 * region-model.cc (region_model::get_rvalue_1): Handle VAR_DECLs with a DECL_HARD_REGISTER by returning UNKNOWN. gcc/testsuite/ChangeLog: PR analyzer/108968 * gcc.dg/analyzer/uninit-pr108968-register.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-03-02analyzer: Support errno for newlibHans-Peter Nilsson1-0/+2
Without this definition, the errno definition for newlib isn't recognized as such, and these tests fail for newlib targets: FAIL: gcc.dg/analyzer/call-summaries-errno.c (test for warnings, line 16) FAIL: gcc.dg/analyzer/call-summaries-errno.c (test for excess errors) FAIL: gcc.dg/analyzer/errno-1.c (test for warnings, line 20) FAIL: gcc.dg/analyzer/errno-1.c (test for excess errors) FAIL: gcc.dg/analyzer/flex-without-call-summaries.c (test for excess errors) FAIL: gcc.dg/analyzer/isatty-1.c (test for warnings, line 31) FAIL: gcc.dg/analyzer/isatty-1.c (test for warnings, line 35) FAIL: gcc.dg/analyzer/isatty-1.c (test for warnings, line 46) FAIL: gcc.dg/analyzer/isatty-1.c (test for warnings, line 56) FAIL: gcc.dg/analyzer/isatty-1.c (test for excess errors) gcc/analyzer: * kf.cc (register_known_functions): Add __errno function for newlib.
2023-03-02Daily bump.GCC Administrator1-0/+21
2023-03-01analyzer: fixes to side-effects for built-in functions [PR107565]David Malcolm1-25/+19
Previously, if the analyzer saw a call to a non-pure and non-const built-in function that it didn't have explicit knowledge of the behavior of, it would fall back to assuming that the builtin could have arbitrary behavior, similar to a function defined outside of the current TU. However, this only worked for BUILTIN_NORMAL functions that matched gimple_builtin_call_types_compatible_p; for BUILT_IN_FRONTEND and BUILT_IN_MD, and for mismatched types the analyzer would erroneously assume that the builtin had no side-effects, leading e.g. to PR analyzer/107565, where the analyzer falsely reported that x was still uninitialized after this target-specific builtin: _1 = __builtin_ia32_rdrand64_step (&x); This patch generalizes the handling to cover all classes of builtin, fixing the above false positive. Unfortunately this patch regresses gcc.dg/analyzer/pr99716-1.c due to the: fprintf (fp, "hello"); being optimized to: __builtin_fwrite ("hello", 1, (ssizetype)5, fp_6); and the latter has gimple_builtin_call_types_compatible_p return false, whereas the original call had it return true. I'm assuming that this is an optimization bug, and have filed it as PR middle-end/108988. The effect on the analyzer is that it fails to recognize the call to __builtin_fwrite and instead assumes arbitraty side-effects (including that it could call fclose on fp, hence the report about the leak goes away). I tried various more involved fixes with new heuristics for handling built-ins that aren't explicitly covered by the analyzer, but those fixes tended to introduce many more regressions, so I'm going with this simpler fix. gcc/analyzer/ChangeLog: PR analyzer/107565 * region-model.cc (region_model::on_call_pre): Flatten logic by returning early. Consolidate logic for detecting const and pure functions. When considering whether an unhandled built-in function has side-effects, consider all kinds of builtin, rather than just BUILT_IN_NORMAL, and don't require gimple_builtin_call_types_compatible_p. gcc/testsuite/ChangeLog: PR analyzer/107565 * gcc.dg/analyzer/builtins-pr107565.c: New test. * gcc.dg/analyzer/pr99716-1.c (test_2): Mark the leak as xfailing. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-03-01analyzer: fix infinite recursion false +ves [PR108935]David Malcolm1-51/+100
gcc/analyzer/ChangeLog: PR analyzer/108935 * infinite-recursion.cc (contains_unknown_p): New. (sufficiently_different_region_binding_p): New function, splitting out inner loop from... (sufficiently_different_p): ...here. Extend detection of unknown svalues to also include svalues that contain unknown. Treat changes in frames below the entry to the recursion as being sufficiently different to reject being an infinite recursion. gcc/testsuite/ChangeLog: PR analyzer/108935 * gcc.dg/analyzer/infinite-recursion-pr108935-1.c: New test. * gcc.dg/analyzer/infinite-recursion-pr108935-1a.c: New test. * gcc.dg/analyzer/infinite-recursion-pr108935-2.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-02-22Daily bump.GCC Administrator1-0/+17
2023-02-21analyzer: stop exploring the path after certain diagnostics [PR108830]David Malcolm6-7/+64
PR analyzer/108830 reports a situation in which there are lots of followup -Wanalyzer-null-dereference warnings after the first access of a NULL pointer, leading to very noisy output from -fanalyzer. The analyzer's logic for stopping emitting multiple warnings from a state machine doesn't quite work for NULL pointers: it attempts to transition the malloc state machine's NULL pointer to the "stop" state, which doesn't seem to make much sense in retrospect, and seems to get confused over types. Similarly, poisoned_value_diagnostic can be very noisy for uninit variables, emitting a warning for every access to an uninitialized variable. In theory, region_model::check_for_poison makes some attempts to suppress followups, but only for the symbolic value itself; if the user's code keeps accessing the same region, we would get a warning on each one. For example, this showed up in Doom's s_sound.c where there were 7 followup uninit warnings after the first uninit warning in "S_ChangeMusic". This patch adds an extra mechanism, giving pending diagnostics the option of stopping the analysis of an execution path if they're saved for emission on it, and turning this on for these warnings: -Wanalyzer-null-dereference -Wanalyzer-null-argument -Wanalyzer-use-after-free -Wanalyzer-use-of-pointer-in-stale-stack-frame -Wanalyzer-use-of-uninitialized-value Doing so should hopefully reduce the cascades of diagnostics that -fanalyzer can sometimes emit. I added a -fno-analyzer-suppress-followups for the cases where you really want the followup warnings (e.g. in some DejaGnu tests, and for microbenchmarks of UB detection, such as PR analyzer/104224). Integration testing shows this patch reduces the number of probable false positives reported by 94, and finds one more true positive: Comparison: 9.34% -> 10.91% GOOD: 66 -> 67 (+1) BAD: 641 -> 547 (-94) where the affected warnings/projects are: -Wanalyzer-null-dereference: 0.00% GOOD: 0 BAD: 269 -> 239 (-30) Unclassified: 257 -> 228 (-29) apr-1.7.0: 12 -> 5 (-7) doom: 1 -> 0 (-1) haproxy-2.7.1: 47 -> 41 (-6) ImageMagick-7.1.0-57: 13 -> 9 (-4) qemu-7.2.0: 165 -> 154 (-11) Known false: 7 -> 6 (-1) xz-5.4.0: 4 -> 3 (-1) -Wanalyzer-use-of-uninitialized-value: 0.00% GOOD: 0 BAD: 143 -> 80 (-63) Known false: 47 -> 16 (-31) doom: 42 -> 11 (-31) Unclassified: 96 -> 64 (-32) coreutils-9.1: 14 -> 10 (-4) haproxy-2.7.1: 29 -> 23 (-6) qemu-7.2.0: 48 -> 26 (-22) -Wanalyzer-null-argument: 0.00% -> 2.33% GOOD: 0 -> 1 (+1) BAD: 43 -> 42 (-1) Unclassified: 39 -> 38 (-1) due to coreutils-9.1: 9 -> 8 (-1) True positive: 0 -> 1 (+1) (in haproxy-2.7.1) gcc/analyzer/ChangeLog: PR analyzer/108830 * analyzer.opt (fanalyzer-suppress-followups): New option. * engine.cc (impl_region_model_context::warn): Terminate the path if the diagnostic's terminate_path_p vfunc returns true and -fanalyzer-suppress-followups is true (the default). (impl_sm_context::warn): Likewise, for both overloads. * pending-diagnostic.h (pending_diagnostic::terminate_path_p): New vfunc. * program-state.cc (program_state::on_edge): Terminate the path if the ctxt requests it during updating the edge. * region-model.cc (poisoned_value_diagnostic::terminate_path_p): New vfunc. * sm-malloc.cc (null_deref::terminate_path_p): New vfunc. (null_arg::terminate_path_p): New vfunc. gcc/ChangeLog: PR analyzer/108830 * doc/invoke.texi: Document -fno-analyzer-suppress-followups. gcc/testsuite/ChangeLog: PR analyzer/108830 * gcc.dg/analyzer/attribute-nonnull.c: Update for -Wanalyzer-use-of-uninitialized-value terminating analysis along a path. * gcc.dg/analyzer/call-summaries-2.c: Likewise. * gcc.dg/analyzer/data-model-1.c: Likewise. * gcc.dg/analyzer/data-model-5.c: Likewise. * gcc.dg/analyzer/doom-s_sound-pr108867.c: New test. * gcc.dg/analyzer/memset-CVE-2017-18549-1.c: Add -fno-analyzer-suppress-followups. * gcc.dg/analyzer/null-deref-pr108830.c: New test. * gcc.dg/analyzer/pipe-1.c: Add -fno-analyzer-suppress-followups. * gcc.dg/analyzer/pipe-void-return.c: Likewise. * gcc.dg/analyzer/pipe2-1.c: Likewise. * gcc.dg/analyzer/pr101547.c: Update for -Wanalyzer-use-of-uninitialized-value terminating analysis along a path. * gcc.dg/analyzer/pr101875.c: Likewise. * gcc.dg/analyzer/pr104224-split.c: New test, based on... * gcc.dg/analyzer/pr104224.c: Add -fno-analyzer-suppress-followups. * gcc.dg/analyzer/realloc-2.c: Add -fno-analyzer-suppress-followups. * gcc.dg/analyzer/realloc-3.c: Likewise. * gcc.dg/analyzer/realloc-5.c: Likewise. * gcc.dg/analyzer/stdarg-1-ms_abi.c: Likewise. * gcc.dg/analyzer/stdarg-1-sysv_abi.c: Likewise. * gcc.dg/analyzer/stdarg-1.c: Likewise. * gcc.dg/analyzer/symbolic-1.c: Likewise. * gcc.dg/analyzer/symbolic-7.c: Update for -Wanalyzer-use-of-uninitialized-value terminating analysis along a path. * gcc.dg/analyzer/uninit-4.c: Likewise. * gcc.dg/analyzer/uninit-8.c: New test. * gcc.dg/analyzer/uninit-pr94713.c: Update for -Wanalyzer-use-of-uninitialized-value terminating analysis along a path. * gcc.dg/analyzer/zlib-6a.c: Add -fno-analyzer-suppress-followups. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-02-17Daily bump.GCC Administrator1-0/+17
2023-02-16analyzer: respect some conditions from bit masks [PR108806]David Malcolm3-1/+175
PR analyzer/108806 reports false +ves seen from -fanalyzer on code like this in qemu-7.2.0's hw/intc/omap_intc.c: [...snip...] struct omap_intr_handler_bank_s* bank = NULL; if ((offset & 0xf80) == 0x80) { [...set "bank" to non-NULL...] } switch (offset) { [...snip various cases that don't deref "bank"...] case 0x80: return bank->inputs; case 0x84: return bank->mask; [...etc...] } where the analyzer falsely complains about execution paths in which "(offset & 0xf80) == 0x80" was false (leaving "bank" as NULL), but then in which "switch (offset)" goes to a case for which "(offset & 0xf80) == 0x80" is true and dereferences NULL "bank", i.e. paths in which "(offset & 0xf80) == 0x80" is both true *and* false. This patch adds enough logic to constraint_manager for -fanalyzer to reject such execution paths as impossible, fixing the false +ves. Integration testing shows this eliminates 20 probable false positives: Comparison: 9.08% -> 9.34% GOOD: 66 BAD: 661 -> 641 (-20) where the affected warnings/projects are: -Wanalyzer-null-dereference: 0.00% GOOD: 0 BAD: 279 -> 269 (-10) qemu-7.2.0: 175 -> 165 (-10) -Wanalyzer-use-of-uninitialized-value: 0.00% GOOD: 0 BAD: 153 -> 143 (-10) coreutils-9.1: 18 -> 14 (-4) qemu-7.2.0: 54 -> 48 (-6) gcc/analyzer/ChangeLog: PR analyzer/108806 * constraint-manager.cc (bounded_range::dump_to_pp): Use bounded_range::singleton_p. (constraint_manager::add_bounded_ranges): Handle singleton ranges by adding an EQ_EXPR constraint. (constraint_manager::impossible_derived_conditions_p): New. (constraint_manager::eval_condition): Reject EQ_EXPR when it would imply impossible derived conditions. (selftest::test_bits): New. (selftest::run_constraint_manager_tests): Run it. * constraint-manager.h (bounded_range::singleton_p): New. (constraint_manager::impossible_derived_conditions_p): New decl. * region-model.cc (region_model::get_rvalue_1): Handle BIT_AND_EXPR, BIT_IOR_EXPR, and BIT_XOR_EXPR. gcc/testsuite/ChangeLog: PR analyzer/108806 * gcc.dg/analyzer/null-deref-pr108806-qemu.c: New test. * gcc.dg/analyzer/pr103217.c: Add -Wno-analyzer-too-complex. * gcc.dg/analyzer/switch.c (test_bitmask_1): New. (test_bitmask_2): New. * gcc.dg/analyzer/uninit-pr108806-qemu.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-02-16Daily bump.GCC Administrator1-0/+35
2023-02-15analyzer: fix uninit false +ves [PR108664,PR108666,PR108725]David Malcolm8-24/+146
This patch updates poisoned_value_diagnostic so that, where possible, it checks to see if the value is still poisoned along the execution path seen during feasibility analysis, rather than just that seen in the exploded graph. Integration testing shows this reduction in the number of false positives: -Wanalyzer-use-of-uninitialized-value: 191 -> 153 (-38) where the changes happen in: coreutils-9.1: 34 -> 20 (-14) qemu-7.2.0: 78 -> 54 (-24) gcc/analyzer/ChangeLog: PR analyzer/108664 PR analyzer/108666 PR analyzer/108725 * diagnostic-manager.cc (epath_finder::get_best_epath): Add "target_stmt" param. (epath_finder::explore_feasible_paths): Likewise. (epath_finder::process_worklist_item): Likewise. (saved_diagnostic::calc_best_epath): Pass m_stmt to epath_finder::get_best_epath. * engine.cc (feasibility_state::maybe_update_for_edge): Move per-stmt logic to... (feasibility_state::update_for_stmt): ...this new function. * exploded-graph.h (feasibility_state::update_for_stmt): New decl. * feasible-graph.cc (feasible_node::get_state_at_stmt): New. * feasible-graph.h: Include "analyzer/exploded-graph.h". (feasible_node::get_state_at_stmt): New decl. * infinite-recursion.cc (infinite_recursion_diagnostic::check_valid_fpath_p): Update for vfunc signature change. * pending-diagnostic.h (pending_diagnostic::check_valid_fpath_p): Convert first param to a reference. Add stmt param. * region-model.cc: Include "analyzer/feasible-graph.h". (poisoned_value_diagnostic::poisoned_value_diagnostic): Add "check_expr" param. (poisoned_value_diagnostic::check_valid_fpath_p): New. (poisoned_value_diagnostic::m_check_expr): New field. (region_model::check_for_poison): Attempt to supply a check_expr to the diagnostic (region_model::deref_rvalue): Add NULL for new check_expr param of poisoned_value_diagnostic. (region_model::get_or_create_region_for_heap_alloc): Don't reuse regions that are marked as TOUCHED. gcc/testsuite/ChangeLog: PR analyzer/108664 PR analyzer/108666 PR analyzer/108725 * gcc.dg/analyzer/coreutils-cksum-pr108664.c: New test. * gcc.dg/analyzer/coreutils-sum-pr108666.c: New test. * gcc.dg/analyzer/torture/uninit-pr108725.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-02-11Daily bump.GCC Administrator1-0/+6
2023-02-10analyzer: don't warn for deref-before-check for checks in macros [PR108745]David Malcolm1-0/+37
Integration testing shows this patch fixes all 9 known false positives from -Wanalyzer-deref-before-check within ImageMagick-7.1.0-57, and eliminates 34 further as-yet unassessed such diagnostics, without eliminating the 1 known true positive. This improves the rate of true positives for the warning from 1.56% to 4.76% of the total: -Wanalyzer-deref-before-check: 1.56% -> 4.76% (GOOD: 1 BAD: 63->20) TRUE: 1 FALSE: 15 -> 6 (-9) ImageMagick-7.1.0-57: 9 -> 0 (-9) TODO: 48 -> 14 (-34) ImageMagick-7.1.0-57: 21 -> 1 (-20) qemu-7.2.0: 25 -> 11 (-14) gcc/analyzer/ChangeLog: PR analyzer/108745 * sm-malloc.cc (deref_before_check::emit): Reject the warning if the check occurs within a macro defintion. gcc/testsuite/ChangeLog: PR analyzer/108745 * gcc.dg/analyzer/deref-before-check-macro-pr108745.c: New test. * gcc.dg/analyzer/deref-before-check-macro.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-02-10Daily bump.GCC Administrator1-0/+6
2023-02-09analyzer: fix further overzealous state purging [PR108733]David Malcolm1-0/+2
PR analyzer/108733 reports various false positives in qemu from -Wanalyzer-use-of-uninitialized-value with __attribute__((cleanup)) at -O1 and above. Root cause is that the state-purging code was failing to treat: _25 = MEM[(void * *)&val]; as a usage of "val", leading to it erroneously purging the initialization of "val" along an execution path that didn't otherwise use "val", apart from the __attribute__((cleanup)). Fixed thusly. Integration testing on the patch show this change in the number of diagnostics: -Wanalyzer-use-of-uninitialized-value coreutils-9.1: 18 -> 16 (-2) qemu-7.2.0: 87 -> 80 (-7) where all that I investigated appear to have been false positives, hence an improvement. gcc/analyzer/ChangeLog: PR analyzer/108733 * state-purge.cc (get_candidate_for_purging): Add ADDR_EXPR and MEM_REF. gcc/testsuite/ChangeLog: PR analyzer/108733 * gcc.dg/analyzer/torture/uninit-pr108733.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-02-09Daily bump.GCC Administrator1-0/+7
2023-02-08analyzer: fix overzealous state purging with on-stack structs [PR108704]David Malcolm1-1/+14
PR analyzer/108704 reports many false positives seen from -Wanalyzer-use-of-uninitialized-value on qemu's softfloat.c on code like the following: struct st s; s = foo (); s = bar (s); // bogusly reports that s is uninitialized here where e.g. "struct st" is "floatx80" in the qemu examples. The root cause is overzealous purging of on-stack structs in the code I added in r12-7718-gfaacafd2306ad7, where at: s = bar (s); state_purge_per_decl::process_point_backwards "sees" the assignment to 's' and stops processing, effectively treating 's' as unneeded before this stmt, not noticing the use of 's' in the argument. Fixed thusly. The patch greatly reduces the number of -Wanalyzer-use-of-uninitialized-value warnings from my integration tests: ImageMagick-7.1.0-57: 10 -> 6 (-4) qemu-7.2: 858 -> 87 (-771) haproxy-2.7.1: 1 -> 0 (-1) All of the above that I've examined appear to be false positives. gcc/analyzer/ChangeLog: PR analyzer/108704 * state-purge.cc (state_purge_per_decl::process_point_backwards): Don't stop processing the decl if it's fully overwritten by this stmt if it's also used by this stmt. gcc/testsuite/ChangeLog: PR analyzer/108704 * gcc.dg/analyzer/uninit-7.c: New test. * gcc.dg/analyzer/uninit-pr108704.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-02-08Daily bump.GCC Administrator1-0/+7
2023-02-07analyzer: fix -Wanalyzer-use-of-uninitialized-value false +ve on "read" ↵David Malcolm2-1/+42
[PR108661] My integration testing shows many false positives from -Wanalyzer-use-of-uninitialized-value. One cause turns out to be that as of r13-1404-g97baacba963c06 fd_state_machine::on_stmt recognizes calls to "read", and returns true, so that region_model::on_call_post doesn't call handle_unrecognized_call on them, and so the analyzer erroneously "thinks" that the buffer pointed to by "read" is never touched by the "read" call. This works for "fread" because sm-file.cc implements kf_fread, which handles calls to "fread" by clobbering the buffer pointed to. In the long term we should probably be smarter about this and bifurcate the analysis to consider e.g. errors vs full reads vs partial reads, etc (which I'm tracking in PR analyzer/108689). In the meantime, this patch adds a kf_read for "read" analogous to the one for "fread", fixing 6 false positives seen in git-2.39.0 and 2 in haproxy-2.7.1. gcc/analyzer/ChangeLog: PR analyzer/108661 * sm-fd.cc (class kf_read): New. (register_known_fd_functions): Register "read". * sm-file.cc (class kf_fread): Update comment. gcc/testsuite/ChangeLog: PR analyzer/108661 * gcc.dg/analyzer/fread-pr108661.c: New test. * gcc.dg/analyzer/read-pr108661.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-02-03Daily bump.GCC Administrator1-0/+8
2023-02-02analyzer: fix -Wanalyzer-fd-type-mismatch false +ve on "listen" [PR108633]David Malcolm1-2/+6
gcc/analyzer/ChangeLog: PR analyzer/108633 * sm-fd.cc (fd_state_machine::check_for_fd_attrs): Add missing "continue". (fd_state_machine::on_listen): Don't issue phase-mismatch or type-mismatch warnings for the "invalid" state. gcc/testsuite/ChangeLog: PR analyzer/108633 * gcc.dg/analyzer/fd-pr108633.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-02-02Daily bump.GCC Administrator1-0/+6
2023-01-31analyzer: fix -Wanalyzer-allocation-size false -ve on alloca [PR108616]David Malcolm1-0/+6
gcc/analyzer/ChangeLog: PR analyzer/108616 * pending-diagnostic.cc (fixup_location_in_macro_p): Add "alloca" to macros that we shouldn't unwind inside. gcc/testsuite/ChangeLog: PR analyzer/108616 * gcc.dg/analyzer/allocation-size-multiline-3.c: New test. * gcc.dg/analyzer/test-alloca.h: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-01-27Daily bump.GCC Administrator1-0/+20
2023-01-26analyzer: fix false positives from -Wanalyzer-infinite-recursion [PR108524]David Malcolm4-5/+132
Reject -Wanalyzer-infinite-recursion diagnostics in which control flow has been affected by conjured_svalues between the initial call to a function and the subsequent entry to that function. This prevents false positives such as in qemu's recursive JSON parser where function calls are changing state in the rest of the program (e.g. consuming tokens), despite the modelled state being effectively identical at both nested entrypoints. gcc/analyzer/ChangeLog: PR analyzer/108524 * analyzer.h (class feasible_node): New forward decl. * diagnostic-manager.cc (epath_finder::get_best_epath): Add "pd" param. (epath_finder::explore_feasible_paths): Likewise. (epath_finder::process_worklist_item): Likewise. Use it to call pending_diagnostic::check_valid_fpath_p on the final fpath to give pending_diagnostic a way to add additional restrictions on feasibility. (saved_diagnostic::calc_best_epath): Pass pending_diagnostic to epath_finder::get_best_epath. * infinite-recursion.cc: Include "analyzer/feasible-graph.h". (infinite_recursion_diagnostic::check_valid_fpath_p): New. (infinite_recursion_diagnostic::fedge_uses_conjured_svalue_p): New. (infinite_recursion_diagnostic::expr_uses_conjured_svalue_p): New. * pending-diagnostic.h (pending_diagnostic::check_valid_fpath_p): New vfunc. gcc/testsuite/ChangeLog: PR analyzer/108524 * gcc.dg/analyzer/infinite-recursion-pr108524-1.c: New test. * gcc.dg/analyzer/infinite-recursion-pr108524-2.c: New test. * gcc.dg/analyzer/infinite-recursion-pr108524-qobject-json-parser.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-01-20Daily bump.GCC Administrator1-0/+42
2023-01-19analyzer: use dominator info in -Wanalyzer-deref-before-check [PR108455]David Malcolm8-13/+67
My integration testing [1] of -fanalyzer in GCC 13 is showing a lot of diagnostics from the new -Wanalyzer-deref-before-check warning on real-world C projects, and most of these seem to be false positives. This patch updates the warning to make it much less likely to fire: - only intraprocedural cases are now reported - reject cases in which there are control flow paths to the check that didn't come through the dereference, by looking at BB dominator information. This fixes a false positive seen in git-2.39.0's pack-revindex.c: load_revindex_from_disk (PR analyzer/108455), in which a shared "cleanup:" section checks "data" for NULL, and depending on how much of the function is executed "data" might or might not have already been dereferenced. The counts of -Wanalyzer-deref-before-check diagnostics in [1] before/after this patch show this improvement: Known false positives: 6 -> 0 (-6) Known true positives: 1 -> 1 Unclassified positives: 123 -> 63 (-60) [1] https://github.com/davidmalcolm/gcc-analyzer-integration-tests gcc/analyzer/ChangeLog: PR analyzer/108455 * analyzer.h (class checker_event): New forward decl. (class state_change_event): Indent. (class warning_event): New forward decl. * checker-event.cc (state_change_event::state_change_event): Add "enode" param. (warning_event::get_desc): Update for new param of evdesc::final_event ctor. * checker-event.h (state_change_event::state_change_event): Add "enode" param. (state_change_event::get_exploded_node): New accessor. (state_change_event::m_enode): New field. (warning_event::warning_event): New "enode" param. (warning_event::get_exploded_node): New accessor. (warning_event::m_enode): New field. * diagnostic-manager.cc (state_change_event_creator::on_global_state_change): Pass src_node to state_change_event ctor. (state_change_event_creator::on_state_change): Likewise. (null_assignment_sm_context::set_next_state): Pass NULL for new param of state_change_event ctor. * infinite-recursion.cc (infinite_recursion_diagnostic::add_final_event): Update for new param of warning_event ctor. * pending-diagnostic.cc (pending_diagnostic::add_final_event): Pass enode to warning_event ctor. * pending-diagnostic.h (evdesc::final_event): Add reference to warning_event. * sm-malloc.cc: Include "analyzer/checker-event.h" and "analyzer/exploded-graph.h". (deref_before_check::deref_before_check): Initialize new fields. (deref_before_check::emit): Reject warnings in which we were unable to determine the enodes of the dereference and the check. Reject warnings interprocedural warnings. Reject warnings in which the dereference doesn't dominate the check. (deref_before_check::describe_state_change): Set m_deref_enode. (deref_before_check::describe_final_event): Set m_check_enode. (deref_before_check::m_deref_enode): New field. (deref_before_check::m_check_enode): New field. gcc/testsuite/ChangeLog: PR analyzer/108455 * gcc.dg/analyzer/deref-before-check-1.c: Add test coverage involving dominance. * gcc.dg/analyzer/deref-before-check-pr108455-1.c: New test. * gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-01-16Update copyright years.Jakub Jelinek85-85/+85
2023-01-15Daily bump.GCC Administrator1-0/+19
2023-01-13analyzer: add heuristics for switch on enum type [PR105273]David Malcolm5-2/+163
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>
2023-01-12Daily bump.GCC Administrator1-0/+14
2023-01-11analyzer: fix leak false positives on "*UNKNOWN = PTR;" [PR108252]David Malcolm3-10/+80
PR analyzer/108252 reports a false positive from -Wanalyzer-malloc-leak on code like this: *ptr_ptr = strdup(EXPR); where ptr_ptr is an UNKNOWN_VALUE. When we handle: *UNKNOWN = PTR; store::set_value normally marks *PTR as having escaped, and this means we don't report PTR as leaking when the last usage of PTR is lost. However this only works for cases where PTR is a region_svalue. In the example in the bug, it's a conjured_svalue, rather than a region_svalue. A similar problem can arise for FDs, which aren't pointers. This patch fixes the bug by updating store::set_value to mark any values stored via *UNKNOWN = VAL as not leaking. Additionally, sm-malloc.cc's known_allocator_p hardcodes strdup and strndup as allocators (and thus transitioning their result to "unchecked"), but we don't implement known_functions for these, leading to the LHS being a CONJURED_SVALUE, rather than a region_svalue to a heap-allocated region. A similar issue happens with functions marked with __attribute__((malloc)). As part of a "belt and braces" fix, the patch also updates the handling of these functions, so that they use heap-allocated regions. gcc/analyzer/ChangeLog: PR analyzer/108252 * kf.cc (class kf_strdup): New. (class kf_strndup): New. (register_known_functions): Register them. * region-model.cc (region_model::on_call_pre): Use &HEAP_ALLOCATED_REGION for the default result of an external function with the "malloc" attribute, rather than CONJURED_SVALUE. (region_model::get_or_create_region_for_heap_alloc): Allow "size_in_bytes" to be NULL. * store.cc (store::set_value): When handling *UNKNOWN = VAL, mark VAL as "maybe bound". gcc/testsuite/ChangeLog: PR analyzer/108252 * gcc.dg/analyzer/attr-malloc-pr108252.c: New test. * gcc.dg/analyzer/fd-leak-pr108252.c: New test. * gcc.dg/analyzer/flex-with-call-summaries.c: Remove xfail from warning false +ve directives. * gcc.dg/analyzer/pr103217-2.c: Add -Wno-analyzer-too-complex. * gcc.dg/analyzer/pr103217-3.c: Likewise. * gcc.dg/analyzer/strdup-pr108252.c: New test. * gcc.dg/analyzer/strndup-pr108252.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2023-01-02Update Copyright year in ChangeLog filesJakub Jelinek1-1/+1
2022 -> 2023
2022-12-17Daily bump.GCC Administrator1-0/+21
2022-12-16analyzer: add src_region param to region_model::check_for_poison [PR106479]David Malcolm6-8/+12
PR analyzer/106479 notes that we don't always show the region-creation event for a memmove from an uninitialized stack region. This occurs when using kf_memcpy_memmove. Fix by passing a src_region hint to region_model::check_for_poison. gcc/analyzer/ChangeLog: PR analyzer/106479 * kf.cc (kf_memcpy_memmove::impl_call_pre): Pass in source region to region_model::check_for_poison. * region-model-asm.cc (region_model::on_asm_stmt): Pass NULL region to region_model::check_for_poison. * region-model.cc (region_model::check_for_poison): Add "src_region" param, and pass it to poisoned_value_diagnostic. (region_model::on_assignment): Pass NULL region to region_model::check_for_poison. (region_model::get_rvalue): Likewise. * region-model.h (region_model::check_for_poison): Add "src_region" param. * sm-fd.cc (fd_state_machine::on_accept): Pass in source region to region_model::check_for_poison. * varargs.cc (kf_va_copy::impl_call_pre): Pass NULL region to region_model::check_for_poison. (kf_va_arg::impl_call_pre): Pass in source region to region_model::check_for_poison. gcc/testsuite/ChangeLog: PR analyzer/106479 * gcc.dg/analyzer/pr104308.c (test_memmove_within_uninit): Remove xfail on region creation event. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-12-15Daily bump.GCC Administrator1-0/+12
2022-12-14analyzer: don't call binding_key::make on empty regions [PR108065]David Malcolm2-0/+17
gcc/analyzer/ChangeLog: PR analyzer/108065 * region.cc (decl_region::get_svalue_for_initializer): Bail out to avoid calling binding_key::make with an empty region. * store.cc (binding_map::apply_ctor_val_to_range): Likewise. (binding_map::apply_ctor_pair_to_child_region): Likewise. (binding_cluster::bind): Likewise. (binding_cluster::purge_region): Likewise. (binding_cluster::maybe_get_compound_binding): Likewise. (binding_cluster::maybe_get_simple_value): Likewise. gcc/testsuite/ChangeLog: PR analyzer/108065 * gfortran.dg/analyzer/pr108065.f90: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-12-10Daily bump.GCC Administrator1-0/+36
2022-12-08analyzer: rename region-model-impl-calls.cc to kf.ccDavid Malcolm3-1/+14
gcc/ChangeLog: * Makefile.in (ANALYZER_OBJS): Update for renaming of analyzer/region-model-impl-calls.cc to analyzer/kf.cc. gcc/analyzer/ChangeLog: * analyzer.h (class known_function): Expand comment. * region-model-impl-calls.cc: Rename to... * kf.cc: ...this. * known-function-manager.h (class known_function_manager): Add leading comment. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-12-08analyzer: fix ICE on region creation during get_referenced_base_regions ↵David Malcolm5-7/+7
[PR108003] gcc/analyzer/ChangeLog: PR analyzer/108003 * call-summary.cc (call_summary_replay::convert_region_from_summary_1): Convert heap_regs_in_use from auto_sbitmap to auto_bitmap. * region-model-manager.cc (region_model_manager::get_or_create_region_for_heap_alloc): Convert from sbitmap to bitmap. * region-model-manager.h: Likewise. * region-model.cc (region_model::get_or_create_region_for_heap_alloc): Convert from auto_sbitmap to auto_bitmap. (region_model::get_referenced_base_regions): Likewise. * region-model.h: Include "bitmap.h" rather than "sbitmap.h". (region_model::get_referenced_base_regions): Convert from auto_sbitmap to auto_bitmap. gcc/testsuite/ChangeLog: PR analyzer/108003 * g++.dg/analyzer/pr108003.C: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>