aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer
AgeCommit message (Collapse)AuthorFilesLines
2022-01-11analyzer: fix false +ve on bitwise binops (PR analyzer/102692)David Malcolm4-12/+109
PR analyzer/102692 reports a false positive at -O2 from -Wanalyzer-null-dereference on: if (!p || q || !p->next) At the gimple level, -O2 has converted the first || into bitwise or controlling a jump: _4 = _2 | _3; if (_4 != 0) and a recursive call has been converted to iteration. The analyzer hits the symbolic value complexity limit whilst analyzing the iteration and hits a case where _2 is (_Bool)1 (i.e. true) and _3 (i.e. q) is UNKNOWN(_Bool). There are two issues leading to the false positive; fixing either issue fixes the false positive; this patch fixes both for good measure: (a) The analyzer erronously treats bitwise ops on UNKNOWN(_Bool) as UNKNOWN, even for case like (1 | UNKNOWN) where we know the result, leading to bogus edges in the exploded graph. The patch fixes these cases. (b) The state-handling code creates "UNKNOWN" symbolic values, as a way to give up when symbolic expressions get too complicated, and in various other cases. This makes sense when building the exploded graph, since we want the analysis to terminate, but doesn't make sense when checking the feasibility along a specific path, where we want precision. The patch prevents all use of "unknown" symbolic values when performing feasibility checking of a path (before it merely stopped doing complexity-checking), by creating a unique placeholder_svalue instead. This fixes the -Wanalyzer-null-dereference false positive. Unfortunately, with GCC 12 there's also a false positive from -Wanalyzer-use-of-uninitialized-value on this code, which is a separate issue that the patch does not fix. gcc/analyzer/ChangeLog: PR analyzer/102692 * diagnostic-manager.cc (class auto_disable_complexity_checks): Rename to... (class auto_checking_feasibility): ...this, updating the calls accordingly. (epath_finder::explore_feasible_paths): Update for renaming. * region-model-manager.cc (region_model_manager::region_model_manager): Update for change from m_check_complexity to m_checking_feasibility. (region_model_manager::reject_if_too_complex): Likewise. (region_model_manager::get_or_create_unknown_svalue): Handle m_checking_feasibility. (region_model_manager::create_unique_svalue): New. (region_model_manager::maybe_fold_binop): Handle BIT_AND_EXPR and BIT_IOR_EXPRs on booleans where we know the result. * region-model.cc (test_binop_svalue_folding): Add test coverage for the above. * region-model.h (region_model_manager::create_unique_svalue): New decl. (region_model_manager::enable_complexity_check): Replace with... (region_model_manager::begin_checking_feasibility): ...this. (region_model_manager::disable_complexity_check): Replace with... (region_model_manager::end_checking_feasibility): ...this. (region_model_manager::m_check_complexity): Replace with... (region_model_manager::m_checking_feasibility): ...this. (region_model_manager::m_managed_dynamic_svalues): New field. gcc/testsuite/ChangeLog: PR analyzer/102692 * gcc.dg/analyzer/pr102692.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-01-08Daily bump.GCC Administrator1-0/+33
2022-01-07analyzer: add logging of aliasingDavid Malcolm6-4/+40
gcc/analyzer/ChangeLog: * engine.cc (impl_run_checkers): Pass logger to engine ctor. * region-model-manager.cc (region_model_manager::region_model_manager): Add logger param and use it to initialize m_logger. * region-model.cc (engine::engine): New. * region-model.h (region_model_manager::region_model_manager): Add logger param. (region_model_manager::get_logger): New. (region_model_manager::m_logger): New field. (engine::engine): New. * store.cc (store_manager::get_logger): New. (store::set_value): Log scope. Log when marking a cluster as unknown due to possible aliasing. * store.h (store_manager::get_logger): New decl.
2022-01-07analyzer: implement __analyzer_dump_escapedDavid Malcolm4-0/+74
PR analyzer/103546 seems to involve an issue in how the analyzer tracks which decls have escaped, so this patch adds a way to directly test this from DejaGnu. gcc/analyzer/ChangeLog: * region-model-impl-calls.cc (cmp_decls): New. (cmp_decls_ptr_ptr): New. (region_model::impl_call_analyzer_dump_escaped): New. * region-model.cc (region_model::on_stmt_pre): Handle __analyzer_dump_escaped. * region-model.h (region_model::impl_call_analyzer_dump_escaped): New decl. * store.h (binding_cluster::get_base_region): New accessor. gcc/ChangeLog: * doc/analyzer.texi (Special Functions for Debugging the Analyzer): Document __analyzer_dump_escaped. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/analyzer-decls.h (__analyzer_dump_escaped): New decl. * gcc.dg/analyzer/escaping-1.c: New test.
2022-01-07analyzer: add region::is_named_decl_pDavid Malcolm2-0/+16
This patch adds a debug function that I've found handy when debugging a problem with handling the decl "yy_buffer_stack" in PR analyzer/103546. gcc/analyzer/ChangeLog: * region.cc (region::is_named_decl_p): New. * region.h (region::is_named_decl_p): New decl. gcc/ChangeLog: * doc/analyzer.texi (Other Debugging Techniques): Document region::is_named_decl_p. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-01-07Daily bump.GCC Administrator1-0/+7
2022-01-06analyzer: make use of may_be_aliased in alias detection [PR103546]David Malcolm1-7/+11
Whilst debugging PR analyzer/103546 (false +ve in flex-generated lexers) I noticed that the analyzer was considering that writes through symbolic pointers could be treated as clobbering static globals such as: static YY_BUFFER_STATE * yy_buffer_stack = NULL; even for such variables that never have their address taken. This patch fixes this issue at least, so that the analyzer can preserve knowledge of such globals on code paths with writes through symbolic pointers. It does not fix the false +ve in the lexer code. gcc/analyzer/ChangeLog: PR analyzer/103546 * store.cc (store::eval_alias_1): Refactor handling of decl regions, adding a test for may_be_aliased, rejecting those for which it returns false. gcc/testsuite/ChangeLog: PR analyzer/103546 * gcc.dg/analyzer/aliasing-3.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-01-03Update copyright years.Jakub Jelinek66-66/+66
2022-01-03Update Copyright in ChangeLog filesJakub Jelinek1-1/+1
Do this separately from all other Copyright updates, as ChangeLog files can be modified only separately.
2021-12-13Daily bump.GCC Administrator1-0/+4
2021-12-12Replace gnu::unique_ptr with std::unique_ptrJonathan Wakely1-1/+1
Now that GCC is compiled as C++11 there is no need to keep the C++03 implementation of gnu::unique_ptr. This removes the unique-ptr.h header and replaces it with <memory> in system.h, and changes the INCLUDE_UNIQUE_PTR macro to INCLUDE_MEMORY. Uses of gnu::unique_ptr and gnu::move can be replaced with std::unique_ptr and std::move. There are no uses of unique_xmalloc_ptr or xmalloc_deleter in GCC. gcc/analyzer/ChangeLog: * engine.cc: Define INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR. gcc/c-family/ChangeLog: * known-headers.cc: Define INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR. * name-hint.h: Likewise. (class name_hint): Use std::unique_ptr instead of gnu::unique_ptr. gcc/c/ChangeLog: * c-decl.c: Define INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR. * c-parser.c: Likewise. gcc/cp/ChangeLog: * error.c: Define INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR. * lex.c: Likewise. * name-lookup.c: Likewise. (class namespace_limit_reached): Use std::unique_ptr instead of gnu::unique_ptr. (suggest_alternatives_for): Use std::move instead of gnu::move. (suggest_alternatives_in_other_namespaces): Likewise. * parser.c: Define INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR. gcc/ChangeLog: * Makefile.in: Remove unique-ptr-tests.o. * selftest-run-tests.c (selftest::run_tests): Remove unique_ptr_tests_cc_tests. * selftest.h (unique_ptr_tests_cc_tests): Remove. * system.h: Check INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR and include <memory> instead of "unique-ptr.h". * unique-ptr-tests.cc: Removed. include/ChangeLog: * unique-ptr.h: Removed.
2021-12-07Daily bump.GCC Administrator1-0/+12
2021-12-06analyzer: fix equivalence class state purging [PR103533]David Malcolm2-2/+149
Whilst debugging state explosions seen when enabling taint detection with -fanalyzer (PR analyzer/103533), I noticed that constraint manager instances could contain stray, redundant constants, such as this instance: constraint_manager: equiv classes: ec0: {(int)0 == [m_constant]‘0’} ec1: {(size_t)4 == [m_constant]‘4’} constraints: where there are two equivalence classes, each just containing a constant, with no constraints using them. This patch makes constraint_manager::canonicalize more aggressive about purging state, handling the case of purging a redundant EC containing just a constant. gcc/analyzer/ChangeLog: PR analyzer/103533 * constraint-manager.cc (equiv_class::contains_non_constant_p): New. (constraint_manager::canonicalize): Call it when determining redundant ECs. (selftest::test_purging): New selftest. (selftest::run_constraint_manager_tests): Likewise. * constraint-manager.h (equiv_class::contains_non_constant_p): New decl. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2021-12-02Daily bump.GCC Administrator1-0/+7
2021-12-01analyzer: fix false leak seen in Juliet 1.3 [PR102471]David Malcolm1-0/+13
Juliet 1.3's CWE415_Double_Free__malloc_free_*_67a.c were showing leak false positives in non-LTO builds; fixed thusly. gcc/analyzer/ChangeLog: PR analyzer/102471 * region-model-reachability.cc (reachable_regions::handle_parm): Treat all svalues within a compound parm has reachable, and those wrapped in a cast. gcc/testsuite/ChangeLog: PR analyzer/102471 * gcc.dg/analyzer/leak-3.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2021-11-30Daily bump.GCC Administrator1-0/+8
2021-11-29analyzer: further false leak fixes due to overzealous state merging [PR103217]David Malcolm1-2/+12
Commit r12-5424-gf573d35147ca8433c102e1721d8c99fc432cb44b fixed a false positive from -Wanalyzer-malloc-leak due to overzealous state merging, erroneously merging two different svalues bound to a particular part of the store when one has sm-state. A further case was discovered by the reporter of PR analyzer/103217, which this patch fixes. In this variant, different states have set different fields of a struct, and on attempting to merge them, the states have a different set of binding keys, leading to one state having an svalue with sm-state, and its peer state having a NULL value for that binding key. The state merger code was erroneously treating them as mergeable to "UNKNOWN". This followup patch fixes things by rejecting such mergers if the non-NULL svalue is not mergeable with "UNKNOWN". gcc/analyzer/ChangeLog: PR analyzer/103217 * store.cc (binding_cluster::can_merge_p): For the "key is bound" vs "key is not bound" merger case, check that the bound svalue is mergeable before merging it to "unknown", rejecting the merger otherwise. gcc/testsuite/ChangeLog: PR analyzer/103217 * gcc.dg/analyzer/pr103217-2.c: New test. * gcc.dg/analyzer/pr103217-3.c: New test. * gcc.dg/analyzer/pr103217-4.c: New test. * gcc.dg/analyzer/pr103217-5.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2021-11-20Daily bump.GCC Administrator1-0/+34
2021-11-19analyzer: fix false leak due to overeager state merging [PR103217]David Malcolm6-12/+71
PR analyzer/103217 reports a false positive from -Wanalyzer-malloc-leak. The root cause is due to overzealous state merger, where the state-merging code decided to merge these two states by merging the stores: state A: clusters within frame: ‘main’@1 cluster for: one_3: CONJURED(val_4 = strdup (src_2(D));, val_4) cluster for: two_4: UNKNOWN(char *) cluster for: one_21: CONJURED(val_4 = strdup (src_2(D));, val_4) state B: clusters within frame: ‘main’@1 cluster for: one_3: UNKNOWN(char *) cluster for: two_4: CONJURED(val_4 = strdup (src_2(D));, val_4) cluster for: two_18: CONJURED(val_4 = strdup (src_2(D));, val_4) into: clusters within frame: ‘main’@1 cluster for: one_3: UNKNOWN(char *) cluster for: two_4: UNKNOWN(char *) cluster for: one_21: UNKNOWN(char *) cluster for: two_18: UNKNOWN(char *) despite "CONJURED(val_4 = strdup (src_2(D));, val_4)" having sm-state, in this case malloc:nonnull ({free}), thus leading to both references to the conjured svalue being lost at merger. This patch tweaks the state merger code so that it will not consider merging two different svalues for the value of a region if either svalue has non-purgable sm-state (in the above example, malloc:nonnull). This fixes the false leak report above. Doing so uncovered an issue with explode-2a.c in which the warnings moved from the correct location to the "while" stmt. This turned out to be a missing call to detect_leaks in phi-handling, which the patch also fixes (in the PK_BEFORE_SUPERNODE case in exploded_graph::process_node). Doing this fixed the regression in explode-2a.c and also fixed the location of the leak warning in explode-1.c. The other side effect of the change is that pr94858-1.c now emits a -Wanalyzer-too-complex warning, since pertinent state is no longer being thrown away. There doesn't seem to be a good way of avoiding this, so the patch also adds -Wno-analyzer-too-complex to that test case (restoring the default). gcc/analyzer/ChangeLog: PR analyzer/103217 * engine.cc (exploded_graph::get_or_create_node): Pass in m_ext_state to program_state::can_merge_with_p. (exploded_graph::process_worklist): Likewise. (exploded_graph::maybe_process_run_of_before_supernode_enodes): Likewise. (exploded_graph::process_node): Add missing call to detect_leaks when handling phi nodes. * program-state.cc (program_state::can_merge_with_p): Add "ext_state" param. Pass it and state ptrs to region_model::can_merge_with_p. (selftest::test_program_state_merging): Update for new ext_state param of program_state::can_merge_with_p. (selftest::test_program_state_merging_2): Likewise. * program-state.h (program_state::can_purge_p): Make const. (program_state::can_merge_with_p): Add "ext_state" param. * region-model.cc: Include "analyzer/program-state.h". (region_model::can_merge_with_p): Add params "ext_state", "state_a", and "state_b", use them when creating model_merger object. (model_merger::mergeable_svalue_p): New. * region-model.h (region_model::can_merge_with_p): Add params "ext_state", "state_a", and "state_b". (model_merger::model_merger) Likewise, initializing new fields. (model_merger::mergeable_svalue_p): New decl. (model_merger::m_ext_state): New field. (model_merger::m_state_a): New field. (model_merger::m_state_b): New field. * svalue.cc (svalue::can_merge_p): Call model_merger::mergeable_svalue_p on both states and reject the merger accordingly. gcc/testsuite/ChangeLog: PR analyzer/103217 * gcc.dg/analyzer/explode-1.c: Update for improvement to location of leak warning. * gcc.dg/analyzer/pr103217.c: New test. * gcc.dg/analyzer/pr94858-1.c: Add -Wno-analyzer-too-complex. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2021-11-18Daily bump.GCC Administrator1-0/+17
2021-11-16analyzer: fix missing -Wanalyzer-write-to-const [PR102695]David Malcolm4-3/+126
This patch fixes -Wanalyzer-write-to-const so that it will complain about attempts to write to functions, to labels. It also "teaches" the analyzer about strchr, in that strchr can either return a pointer into the input area (and thus -Wanalyzer-write-to-const can now complain about writes into a string literal seen this way), or return NULL (and thus the analyzer can complain about NULL dereferences if the result is used without a check). gcc/analyzer/ChangeLog: PR analyzer/102695 * region-model-impl-calls.cc (region_model::impl_call_strchr): New. * region-model-manager.cc (region_model_manager::maybe_fold_unaryop): Simplify cast to pointer type of an existing pointer to a region. * region-model.cc (region_model::on_call_pre): Handle BUILT_IN_STRCHR and "strchr". (write_to_const_diagnostic::emit): Add auto_diagnostic_group. Add alternate wordings for functions and labels. (write_to_const_diagnostic::describe_final_event): Add alternate wordings for functions and labels. (region_model::check_for_writable_region): Handle RK_FUNCTION and RK_LABEL. * region-model.h (region_model::impl_call_strchr): New decl. gcc/testsuite/ChangeLog: PR analyzer/102695 * gcc.dg/analyzer/pr102695.c: New test. * gcc.dg/analyzer/strchr-1.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2021-11-17Daily bump.GCC Administrator1-0/+6
2021-11-16analyzer: fix overeager sharing of bounded_range instances [PR102662]David Malcolm1-1/+3
This was leading to an assertion failure ICE on a switch stmt when using -fstrict-enums, due to erroneously reusing a range involving one enum with a range involving a different enum. gcc/analyzer/ChangeLog: PR analyzer/102662 * constraint-manager.cc (bounded_range::operator==): Require the types to be the same for equality. gcc/testsuite/ChangeLog: PR analyzer/102662 * g++.dg/analyzer/pr102662.C: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2021-11-14Daily bump.GCC Administrator1-0/+73
2021-11-13analyzer: add four new taint-based warningsDavid Malcolm9-112/+875
The initial commit of the analyzer in GCC 10 had a single warning, -Wanalyzer-tainted-array-index and required manually enabling the taint checker with -fanalyzer-checker=taint (due to scaling issues). This patch extends the taint detection to add four new taint-based warnings: -Wanalyzer-tainted-allocation-size for e.g. attacker-controlled malloc/alloca -Wanalyzer-tainted-divisor for detecting where an attacker can inject a divide-by-zero -Wanalyzer-tainted-offset for attacker-controlled pointer offsets -Wanalyzer-tainted-size for e.g. attacker-controlled memset and rewords all the warnings to talk about "attacker-controlled" values rather than "tainted" values. Unfortunately I haven't yet addressed the scaling issues, so all of these still require -fanalyzer-checker=taint (in addition to -fanalyzer). gcc/analyzer/ChangeLog: * analyzer.opt (Wanalyzer-tainted-allocation-size): New. (Wanalyzer-tainted-divisor): New. (Wanalyzer-tainted-offset): New. (Wanalyzer-tainted-size): New. * engine.cc (impl_region_model_context::get_taint_map): New. * exploded-graph.h (impl_region_model_context::get_taint_map): New decl. * program-state.cc (sm_state_map::get_state): Call alt_get_inherited_state. (sm_state_map::impl_set_state): Modify states within compound svalues. (program_state::impl_call_analyzer_dump_state): Undo casts. (selftest::test_program_state_1): Update for new context param of create_region_for_heap_alloc. (selftest::test_program_state_merging): Likewise. * region-model-impl-calls.cc (region_model::impl_call_alloca): Likewise. (region_model::impl_call_calloc): Likewise. (region_model::impl_call_malloc): Likewise. (region_model::impl_call_operator_new): Likewise. (region_model::impl_call_realloc): Likewise. * region-model.cc (region_model::check_region_access): Call check_region_for_taint. (region_model::get_representative_path_var_1): Handle binops. (region_model::create_region_for_heap_alloc): Add "ctxt" param and pass it to set_dynamic_extents. (region_model::create_region_for_alloca): Likewise. (region_model::set_dynamic_extents): Add "ctxt" param and use it to call check_dynamic_size_for_taint. (selftest::test_state_merging): Update for new context param of create_region_for_heap_alloc. (selftest::test_malloc_constraints): Likewise. (selftest::test_malloc): Likewise. (selftest::test_alloca): Likewise for create_region_for_alloca. * region-model.h (region_model::create_region_for_heap_alloc): Add "ctxt" param. (region_model::create_region_for_alloca): Likewise. (region_model::set_dynamic_extents): Likewise. (region_model::check_dynamic_size_for_taint): New decl. (region_model::check_region_for_taint): New decl. (region_model_context::get_taint_map): New vfunc. (noop_region_model_context::get_taint_map): New. * sm-taint.cc: Remove include of "diagnostic-event-id.h"; add includes of "gimple-iterator.h", "tristate.h", "selftest.h", "ordered-hash-map.h", "cgraph.h", "cfg.h", "digraph.h", "analyzer/supergraph.h", "analyzer/call-string.h", "analyzer/program-point.h", "analyzer/store.h", "analyzer/region-model.h", and "analyzer/program-state.h". (enum bounds): Move to top of file. (class taint_diagnostic): New. (class tainted_array_index): Convert to subclass of taint_diagnostic. (tainted_array_index::emit): Add CWE-129. Reword warning to use "attacker-controlled" rather than "tainted". (tainted_array_index::describe_state_change): Move to taint_diagnostic::describe_state_change. (tainted_array_index::describe_final_event): Reword to use "attacker-controlled" rather than "tainted". (class tainted_offset): New. (class tainted_size): New. (class tainted_divisor): New. (class tainted_allocation_size): New. (taint_state_machine::alt_get_inherited_state): New. (taint_state_machine::on_stmt): In assignment handling, remove ARRAY_REF handling in favor of check_region_for_taint. Add detection of tainted divisors. (taint_state_machine::get_taint): New. (taint_state_machine::combine_states): New. (region_model::check_region_for_taint): New. (region_model::check_dynamic_size_for_taint): New. * sm.h (state_machine::alt_get_inherited_state): New. gcc/ChangeLog: * doc/invoke.texi (Static Analyzer Options): Add -Wno-analyzer-tainted-allocation-size, -Wno-analyzer-tainted-divisor, -Wno-analyzer-tainted-offset, and -Wno-analyzer-tainted-size to list. Add -Wanalyzer-tainted-allocation-size, -Wanalyzer-tainted-divisor, -Wanalyzer-tainted-offset, and -Wanalyzer-tainted-size to list of options effectively enabled by -fanalyzer. (-Wanalyzer-tainted-allocation-size): New. (-Wanalyzer-tainted-array-index): Tweak wording; add link to CWE. (-Wanalyzer-tainted-divisor): New. (-Wanalyzer-tainted-offset): New. (-Wanalyzer-tainted-size): New. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/pr93382.c: Tweak expected wording. * gcc.dg/analyzer/taint-alloc-1.c: New test. * gcc.dg/analyzer/taint-alloc-2.c: New test. * gcc.dg/analyzer/taint-divisor-1.c: New test. * gcc.dg/analyzer/taint-1.c: Rename to... * gcc.dg/analyzer/taint-read-index-1.c: ...this. Tweak expected wording. Mark some events as xfail. * gcc.dg/analyzer/taint-read-offset-1.c: New test. * gcc.dg/analyzer/taint-size-1.c: New test. * gcc.dg/analyzer/taint-write-index-1.c: New test. * gcc.dg/analyzer/taint-write-offset-1.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2021-11-13Daily bump.GCC Administrator1-0/+5
2021-11-12analyzer: "__analyzer_dump_state" has no side-effectsDavid Malcolm1-2/+5
gcc/analyzer/ChangeLog: * engine.cc (exploded_node::on_stmt_pre): Return when handling "__analyzer_dump_state". Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2021-11-12Daily bump.GCC Administrator1-0/+4
2021-11-11Apply TLC to control dependence computeRichard Biener1-0/+1
This makes the control dependence compute avoid a find_edge and optimizes allocation by embedding the bitmap head into the vector of control dependences instead of allocating all of them. It also uses a local bitmap obstack. The bitmap changes make it necessary to shuffle some includes. 2021-11-10 Richard Biener <rguenther@suse.de> * cfganal.h (control_dependences::control_dependence_map): Embed bitmap_head. (control_dependences::m_bitmaps): New. * cfganal.c (control_dependences::set_control_dependence_map_bit): Adjust. (control_dependences::clear_control_dependence_bitmap): Likewise. (control_dependences::find_control_dependence): Do not find_edge for the abnormal edge test. (control_dependences::control_dependences): Instead do not add abnormal edges to the edge list. Adjust. (control_dependences::~control_dependences): Likewise. (control_dependences::get_edges_dependent_on): Likewise. * function-tests.c: Include bitmap.h. gcc/analyzer/ * supergraph.cc: Include bitmap.h. gcc/c/ * gimple-parser.c: Shuffle bitmap.h include.
2021-11-05Daily bump.GCC Administrator1-0/+5
2021-11-04analyzer: fix ICE in sm_state_map::dump when dumping treesDavid Malcolm1-0/+1
gcc/analyzer/ChangeLog: * program-state.cc (sm_state_map::dump): Use default_tree_printer as format decoder. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2021-09-17Daily bump.GCC Administrator1-0/+5
2021-09-17analyzer: Fix bootstrap with clangMaxim Blinov1-0/+1
gcc/analyzer/ChangeLog: PR bootstrap/102242 * engine.cc (INCLUDE_UNIQUE_PTR): Define.
2021-09-09Daily bump.GCC Administrator1-0/+12
2021-09-08analyzer: fix ICE when discarding result of realloc [PR102225]David Malcolm4-19/+36
gcc/analyzer/ChangeLog: PR analyzer/102225 * analyzer.h (compat_types_p): New decl. * constraint-manager.cc (constraint_manager::get_or_add_equiv_class): Guard against NULL type when checking for pointer types. * region-model-impl-calls.cc (region_model::impl_call_realloc): Guard against NULL lhs type/region. Guard against the size value not being of a compatible type for dynamic extents. * region-model.cc (compat_types_p): Make non-static. gcc/testsuite/ChangeLog: PR analyzer/102225 * gcc.dg/analyzer/realloc-1.c (test_10): New. * gcc.dg/analyzer/torture/pr102225.c: New test.
2021-08-31Daily bump.GCC Administrator1-0/+103
2021-08-30analyzer: support "bifurcation"; reimplement realloc [PR99260]David Malcolm13-123/+911
Most of the state-management code in the analyzer involves modifying state objects in-place, which implies a single outcome. (I originally implemented in-place modification because I wanted to avoid having to create copies of state objects, and it's now very difficult to change this aspect of the analyzer's design) However, there are various special-cases such as "realloc" for which it's best to split the state into multiple outcomes. This patch adds a mechanism for "bifurcating" the analysis in places where there isn't a split in the CFG, and uses it to implement realloc, in this case treating it as having 3 possible outcomes: - failure, returning NULL - success, growing the buffer in-place without moving it - success, allocating a new buffer, copying the content of the old buffer to it, and freeing the old buffer. gcc/ChangeLog: PR analyzer/99260 * Makefile.in (ANALYZER_OBJS): Add analyzer/call-info.o. gcc/analyzer/ChangeLog: PR analyzer/99260 * analyzer.h (class custom_edge_info): New class, adapted from exploded_edge::custom_info_t. Make member functions const. Make update_model return bool, converting edge param from reference to a pointer, and adding a ctxt param. (class path_context): New class. * call-info.cc: New file. * call-info.h: New file. * engine.cc: Include "analyzer/call-info.h" and <memory>. (impl_region_model_context::impl_region_model_context): Update for new m_path_ctxt field. (impl_region_model_context::bifurcate): New. (impl_region_model_context::terminate_path): New. (impl_region_model_context::get_malloc_map): New. (impl_sm_context::impl_sm_context): Update for new m_path_ctxt field. (impl_sm_context::get_fndecl_for_call): Likewise. (impl_sm_context::set_next_state): Likewise. (impl_sm_context::warn): Likewise. (impl_sm_context::is_zero_assignment): Likewise. (impl_sm_context::get_path_context): New. (impl_sm_context::m_path_ctxt): New. (impl_region_model_context::on_condition): Update for new path_ctxt param. Handle m_enode_for_diag being NULL. (impl_region_model_context::on_phi): Update for new path_ctxt param. (exploded_node::on_stmt): Add path_ctxt param, updating ctor calls to use it as necessary. Use it to bail out after sm-handling, if needed. (exploded_node::detect_leaks): Update for new path_ctxt param. (dynamic_call_info_t::update_model): Update for conversion of exploded_edge::custom_info_t to custom_edge_info. (dynamic_call_info_t::add_events_to_path): Likewise. (rewind_info_t::update_model): Likewise. (rewind_info_t::add_events_to_path): Likewise. (exploded_edge::exploded_edge): Likewise. (exploded_graph::add_edge): Likewise. (exploded_graph::maybe_process_run_of_before_supernode_enodes): Update for new path_ctxt param. (class impl_path_context): New. (exploded_graph::process_node): Update for new path_ctxt param. Create an impl_path_context and pass it to exploded_node::on_stmt. Use it to terminate iterating stmts if terminate_path is called on it. After processing a run of stmts, query path_ctxt to potentially terminate the analysis path, and/or to "bifurcate" the analysis into multiple additional paths. (feasibility_state::maybe_update_for_edge): Update for new update_model ctxt param. * exploded-graph.h (impl_region_model_context::impl_region_model_context): Add path_ctxt param. (impl_region_model_context::bifurcate): New. (impl_region_model_context::terminate_path): New (impl_region_model_context::get_ext_state): New. (impl_region_model_context::get_malloc_map): New. (impl_region_model_context::m_path_ctxt): New field. (exploded_node::on_stmt): Add path_ctxt param. (class exploded_edge::custom_info_t): Move to analyzer.h, renaming to custom_edge_info, and making the changes as noted in analyzer.h above. (exploded_edge::exploded_edge): Update for these changes to exploded_edge::custom_info_t. (exploded_edge::m_custom_info): Likewise. (class dynamic_call_info_t): Likewise. (class rewind_info_t): Likewise. (exploded_graph::add_edge): Likewise. * program-state.cc (program_state::on_edge): Update for new path_ctxt param. (program_state::push_call): Likewise. (program_state::returning_call): Likewise. (program_state::prune_for_point): Likewise. * region-model-impl-calls.cc: Include "analyzer/call-info.h". (call_details::get_fndecl_for_call): New. (region_model::impl_call_realloc): Reimplement. * region-model.cc (region_model::on_call_pre): Move call to impl_call_realloc to... (region_model::on_call_post): ...here. Consolidate creation of call_details instance. (noop_region_model_context::bifurcate): New. (noop_region_model_context::terminate_path): New. * region-model.h (call_details::get_call_stmt): New. (call_details::get_fndecl_for_call): New. (region_model::on_realloc_with_move): New. (region_model_context::bifurcate): New. (region_model_context::terminate_path): New. (region_model_context::get_ext_state): New. (region_model_context::get_malloc_map): New. (noop_region_model_context::bifurcate): New. (noop_region_model_context::terminate_path): New. (noop_region_model_context::get_ext_state): New. (noop_region_model_context::get_malloc_map): New. * sm-malloc.cc: Include "analyzer/program-state.h". (malloc_state_machine::on_realloc_call): Reimplement. (malloc_state_machine::on_realloc_with_move): New. (region_model::on_realloc_with_move): New. * sm-signal.cc (class signal_delivery_edge_info_t): Update for conversion from exploded_edge::custom_info_t to custom_edge_info. * sm.h (sm_context::get_path_context): New. * svalue.cc (svalue::maybe_get_constant): Call unwrap_any_unmergeable. gcc/testsuite/ChangeLog: PR analyzer/99260 * gcc.dg/analyzer/capacity-2.c: Update for changes to realloc analysis. * gcc.dg/analyzer/pr99193-1.c: Likewise. * gcc.dg/analyzer/pr99193-3.c: Likewise. * gcc.dg/analyzer/realloc-1.c: Likewise. Add test coverage for realloc of non-heap pointer, realloc from mismatching allocator, and realloc on a freed pointer. * gcc.dg/analyzer/realloc-2.c: New test.
2021-08-26Daily bump.GCC Administrator1-0/+6
2021-08-25analyzer: Impose recursion limit on indirect calls.Ankur Saini1-0/+14
2021-08-25 Ankur Saini <arsenic@sourceware.org> gcc/analyzer/ChangeLog: PR analyzer/101980 * engine.cc (exploded_graph::maybe_create_dynamic_call): Don't create calls if max recursion limit is reached.
2021-08-24Daily bump.GCC Administrator1-0/+181
2021-08-23analyzer: rewrite of switch handlingDavid Malcolm12-105/+1682
When investigating false positives on the Linux kernel from -Wanalyzer-use-of-uninitialized-value, I noticed that the existing implementation of switch statements in the analyzer is broken. Specifically, the existing implementation assumes a 1:1 association between CFG out-edges from the basic block and case labels in the gimple switch statement. This happened to be the case in the examples I had tested, but there is no such association in general. In particular, in the motivating example: arch/x86/kernel/cpu/mtrr/if.c: mtrr_ioctl the switch statement has 3 blocks, each covering multiple ranges of ioctl command IDs for which different local variables are initialized, which the existing implementation gets badly wrong. [1] This patch reimplements switch handling in the analyzer to eliminate this false assumption - instead, for each out-edge we gather the set of case labels for that out-edge, and use that to determine the set of value ranges for the edge. Avoiding false positives for the above example requires that we accurately track value ranges for symbolic values, so the patch extends constraint_manager with a new bounded_ranges_constraint, adding just enough information to capture the ranges for switch statements whilst retaining combatility with the existing constraint-handling (ultimately I'd prefer to simply throw all of this into a SAT solver and let it track things). Doing so fixes the false positives seen on the Linux kernel and an existing xfail in the test suite. The patch also fixes a long-standing bug in constraint_manager::add_unknown_constraint when updating constraints due to combining equivalence classes, spotted when debugging the same logic for the new kind of constraints. [1] a reduced version of this code is captured in this patch, in gcc.dg/analyzer/torture/switch-3.c gcc/analyzer/ChangeLog: * analyzer.h (struct rejected_constraint): Convert to... (class rejected_constraint): ...this. (class bounded_ranges): New forward decl. (class bounded_ranges_manager): New forward decl. * constraint-manager.cc: Include "analyzer/analyzer-logging.h" and "tree-pretty-print.h". (can_plus_one_p): New. (plus_one): New. (can_minus_one_p): New. (minus_one): New. (bounded_range::bounded_range): New. (dump_cst): New. (bounded_range::dump_to_pp): New. (bounded_range::dump): New. (bounded_range::to_json): New. (bounded_range::set_json_attr): New. (bounded_range::contains_p): New. (bounded_range::intersects_p): New. (bounded_range::operator==): New. (bounded_range::cmp): New. (bounded_ranges::bounded_ranges): New. (bounded_ranges::bounded_ranges): New. (bounded_ranges::bounded_ranges): New. (bounded_ranges::canonicalize): New. (bounded_ranges::validate): New. (bounded_ranges::operator==): New. (bounded_ranges::dump_to_pp): New. (bounded_ranges::dump): New. (bounded_ranges::to_json): New. (bounded_ranges::eval_condition): New. (bounded_ranges::contain_p): New. (bounded_ranges::cmp): New. (bounded_ranges_manager::~bounded_ranges_manager): New. (bounded_ranges_manager::get_or_create_empty): New. (bounded_ranges_manager::get_or_create_point): New. (bounded_ranges_manager::get_or_create_range): New. (bounded_ranges_manager::get_or_create_union): New. (bounded_ranges_manager::get_or_create_intersection): New. (bounded_ranges_manager::get_or_create_inverse): New. (bounded_ranges_manager::consolidate): New. (bounded_ranges_manager::get_or_create_ranges_for_switch): New. (bounded_ranges_manager::create_ranges_for_switch): New. (bounded_ranges_manager::make_case_label_ranges): New. (bounded_ranges_manager::log_stats): New. (bounded_ranges_constraint::print): New. (bounded_ranges_constraint::to_json): New. (bounded_ranges_constraint::operator==): New. (bounded_ranges_constraint::add_to_hash): New. (constraint_manager::constraint_manager): Update for new field m_bounded_ranges_constraints. (constraint_manager::operator=): Likewise. (constraint_manager::hash): Likewise. (constraint_manager::operator==): Likewise. (constraint_manager::print): Likewise. (constraint_manager::dump_to_pp): Likewise. (constraint_manager::to_json): Likewise. (constraint_manager::add_unknown_constraint): Update the lhs_ec_id if necessary in existing constraints when combining equivalence classes. Add similar code for handling m_bounded_ranges_constraints. (constraint_manager::add_constraint_internal): Add comment. (constraint_manager::add_bounded_ranges): New. (constraint_manager::eval_condition): Use new field m_bounded_ranges_constraints. (constraint_manager::purge): Update bounded_ranges_constraint instances. (constraint_manager::canonicalize): Update for new field. (merger_fact_visitor::on_ranges): New. (constraint_manager::for_each_fact): Use new field m_bounded_ranges_constraints. (constraint_manager::validate): Fix off-by-one error needed due to bug fixed above in add_unknown_constraint. Validate the EC IDs in m_bounded_ranges_constraints. (constraint_manager::get_range_manager): New. (selftest::assert_dump_bounded_range_eq): New. (ASSERT_DUMP_BOUNDED_RANGE_EQ): New. (selftest::test_bounded_range): New. (selftest::assert_dump_bounded_ranges_eq): New. (ASSERT_DUMP_BOUNDED_RANGES_EQ): New. (selftest::test_bounded_ranges): New. (selftest::run_constraint_manager_tests): Call the new selftests. * constraint-manager.h (struct bounded_range): New. (struct bounded_ranges): New. (template <> struct default_hash_traits<bounded_ranges::key_t>): New. (class bounded_ranges_manager): New. (fact_visitor::on_ranges): New pure virtual function. (class bounded_ranges_constraint): New. (constraint_manager::add_bounded_ranges): New decl. (constraint_manager::get_range_manager): New decl. (constraint_manager::m_bounded_ranges_constraints): New field. * diagnostic-manager.cc (epath_finder::process_worklist_item): Transfer ownership of rc to add_feasibility_problem. * engine.cc (feasibility_problem::dump_to_pp): Use get_model. * feasible-graph.cc (infeasible_node::dump_dot): Update for conversion of m_rc to a pointer. (feasible_graph::add_feasibility_problem): Pass RC by pointer and take ownership. * feasible-graph.h (infeasible_node::infeasible_node): Pass RC by pointer and take ownership. (infeasible_node::~infeasible_node): New. (infeasible_node::m_rc): Convert to a pointer. (feasible_graph::add_feasibility_problem): Pass RC by pointer and take ownership. * region-model-manager.cc: Include "analyzer/constraint-manager.h". (region_model_manager::region_model_manager): Initializer new field m_range_mgr. (region_model_manager::~region_model_manager): Delete it. (region_model_manager::log_stats): Call log_stats on it. * region-model.cc (region_model::add_constraint): Use new subclass rejected_op_constraint. (region_model::apply_constraints_for_gswitch): Reimplement using bounded_ranges_manager. (rejected_constraint::dump_to_pp): Convert to... (rejected_op_constraint::dump_to_pp): ...this. (rejected_ranges_constraint::dump_to_pp): New. * region-model.h (struct purge_stats): Add field m_num_bounded_ranges_constraints. (region_model_manager::get_range_manager): New. (region_model_manager::m_range_mgr): New. (region_model::get_range_manager): New. (struct rejected_constraint): Split into... (class rejected_constraint):...this new abstract base class, and... (class rejected_op_constraint): ...this new concrete subclass. (class rejected_ranges_constraint): New. * supergraph.cc: Include "tree-cfg.h". (supergraph::supergraph): Drop idx param from add_cfg_edge. (supergraph::add_cfg_edge): Drop idx param. (switch_cfg_superedge::switch_cfg_superedge): Move here from header. Populate m_case_labels with all cases which go to DST. (switch_cfg_superedge::dump_label_to_pp): Reimplement to use m_case_labels. (switch_cfg_superedge::get_case_label): Delete. * supergraph.h (supergraphadd_cfg_edge): Drop "idx" param. (switch_cfg_superedge::switch_cfg_superedge): Drop idx param and move implementation to supergraph.cc. (switch_cfg_superedge::get_case_label): Delete. (switch_cfg_superedge::get_case_labels): New. (switch_cfg_superedge::m_idx): Delete. (switch_cfg_superedge::m_case_labels): New field. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/switch.c: Remove xfail. Add various tests. * gcc.dg/analyzer/torture/switch-2.c: New test. * gcc.dg/analyzer/torture/switch-3.c: New test. * gcc.dg/analyzer/torture/switch-4.c: New test. * gcc.dg/analyzer/torture/switch-5.c: New test.
2021-08-23analyzer: fix ICE with NULL change.m_expr [PR101875]David Malcolm1-4/+14
gcc/analyzer/ChangeLog: PR analyzer/101875 * sm-file.cc (file_diagnostic::describe_state_change): Handle change.m_expr being NULL. gcc/testsuite/ChangeLog: PR analyzer/101875 * gcc.dg/analyzer/pr101875.c: New test.
2021-08-23analyzer: fix ICE when failing to reconstruct a fn ptr [PR101837]David Malcolm1-0/+3
gcc/analyzer/ChangeLog: PR analyzer/101837 * analyzer.cc (maybe_reconstruct_from_def_stmt): Bail if fn is NULL, and assert that it's non-NULL before passing it to build_call_array_loc. gcc/testsuite/ChangeLog: PR analyzer/101837 * gcc.dg/analyzer/pr101837.c: New test.
2021-08-23analyzer: assume that POINTER_PLUS_EXPR of non-NULL is non-NULL [PR101962]David Malcolm1-28/+45
gcc/analyzer/ChangeLog: PR analyzer/101962 * region-model.cc (region_model::eval_condition_without_cm): Refactor comparison against zero, adding a check for POINTER_PLUS_EXPR of non-NULL. gcc/testsuite/ChangeLog: PR analyzer/101962 * gcc.dg/analyzer/data-model-23.c: New test. * gcc.dg/analyzer/pr101962.c: New test.
2021-08-23analyzer: fix uninit false positive on overlapping bindingsDavid Malcolm2-3/+79
gcc/analyzer/ChangeLog: * store.cc (bit_range::intersects_p): New overload. (bit_range::operator-): New. (binding_cluster::maybe_get_compound_binding): Handle the partial overlap case. (selftest::test_bit_range_intersects_p): Add test coverage for new overload of bit_range::intersects_p. * store.h (bit_range::intersects_p): New overload. (bit_range::operator-): New. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/data-model-22.c: New test. * gcc.dg/analyzer/uninit-6.c: New test. * gcc.dg/analyzer/uninit-6b.c: New test.
2021-08-23analyzer: Fix PR analyzer/102020Ankur Saini1-1/+1
2021-08-23 Ankur Saini <arsenic@sourceware.org> gcc/analyzer/ChangeLog: PR analyzer/102020 * diagnostic-manager.cc (diagnostic_manager::prune_for_sm_diagnostic)<case EK_CALL_EDGE>: Fix typo. gcc/testsuite/ChangeLog: PR analyzer/102020 * gcc.dg/analyzer/malloc-callbacks.c : Fix faulty test.
2021-08-22Daily bump.GCC Administrator1-0/+21
2021-08-21analyzer: Fix PR analyzer/101980Ankur Saini5-41/+82
2021-08-19 Ankur Saini <arsenic@sourceware.org> gcc/analyzer/ChangeLog: PR analyzer/101980 * diagnostic-manager.cc (diagnostic_manager::prune_for_sm_diagnostic)<case EK_CALL_EDGE>: Use caller_model only when the supergraph_edge doesn't exixt. (diagnostic_manager::prune_for_sm_diagnostic)<case EK_RETURN_EDGE>: Likewise. * engine.cc (exploded_graph::create_dynamic_call): Rename to... (exploded_graph::maybe_create_dynamic_call): ...this, return call creation status. (exploded_graph::process_node): Handle calls which were not dynamically discovered. * exploded-graph.h (exploded_graph::create_dynamic_call): Rename to... (exploded_graph::maybe_create_dynamic_call): ...this. * region-model.cc (region_model::update_for_gcall): New param, use it to push call to frame. (region_model::update_for_call_superedge): Pass callee function to update_for_gcall. * region-model.h (region_model::update_for_gcall): New param. gcc/testsuite/ChangeLog: PR analyzer/101980 * gcc.dg/analyzer/function-ptr-2.c : Add issue for double 'free'. * gcc.dg/analyzer/malloc-callbacks.c : Fix xfail testcase.
2021-08-19Daily bump.GCC Administrator1-0/+51
2021-08-18analyzer: detect and analyze virtual function callsAnkur Saini1-0/+5
2021-08-15 Ankur Saini <arsenic@sourceware.org> gcc/analyzer/ChangeLog: PR analyzer/97114 * region-model.cc (region_model::get_rvalue_1): Add case for OBJ_TYPE_REF. gcc/testsuite/ChangeLog: PR analyzer/97114 * g++.dg/analyzer/vfunc-2.C: New test. * g++.dg/analyzer/vfunc-3.C: New test. * g++.dg/analyzer/vfunc-4.C: New test. * g++.dg/analyzer/vfunc-5.C: New test.