aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer
AgeCommit message (Collapse)AuthorFilesLines
2022-05-21Daily bump.GCC Administrator1-0/+30
2022-05-20Use "final" and "override" directly, rather than via macrosDavid Malcolm26-557/+557
As of GCC 11 onwards we have required a C++11 compiler, such as GCC 4.8 or later. On the assumption that any such compiler correctly implements "final" and "override", this patch updates the source tree to stop using the FINAL and OVERRIDE macros from ansidecl.h, in favor of simply using "final" and "override" directly. libcpp/ChangeLog: * lex.cc: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". gcc/analyzer/ChangeLog: * analyzer-pass.cc: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * call-info.h: Likewise. * checker-path.h: Likewise. * constraint-manager.cc: Likewise. * diagnostic-manager.cc: Likewise. * engine.cc: Likewise. * exploded-graph.h: Likewise. * feasible-graph.h: Likewise. * pending-diagnostic.h: Likewise. * region-model-impl-calls.cc: Likewise. * region-model.cc: Likewise. * region-model.h: Likewise. * region.h: Likewise. * sm-file.cc: Likewise. * sm-malloc.cc: Likewise. * sm-pattern-test.cc: Likewise. * sm-sensitive.cc: Likewise. * sm-signal.cc: Likewise. * sm-taint.cc: Likewise. * state-purge.h: Likewise. * store.cc: Likewise. * store.h: Likewise. * supergraph.h: Likewise. * svalue.h: Likewise. * trimmed-graph.h: Likewise. * varargs.cc: Likewise. gcc/c-family/ChangeLog: * c-format.cc: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * c-pretty-print.h: Likewise. gcc/cp/ChangeLog: * cxx-pretty-print.h: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * error.cc: Likewise. gcc/jit/ChangeLog: * jit-playback.h: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * jit-recording.cc: Likewise. * jit-recording.h: Likewise. gcc/ChangeLog: * config/aarch64/aarch64-sve-builtins-base.cc: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * config/aarch64/aarch64-sve-builtins-functions.h: Likewise. * config/aarch64/aarch64-sve-builtins-shapes.cc: Likewise. * config/aarch64/aarch64-sve-builtins-sve2.cc: Likewise. * diagnostic-path.h: Likewise. * digraph.cc: Likewise. * gcc-rich-location.h: Likewise. * gimple-array-bounds.cc: Likewise. * gimple-loop-versioning.cc: Likewise. * gimple-range-cache.cc: Likewise. * gimple-range-cache.h: Likewise. * gimple-range-fold.cc: Likewise. * gimple-range-fold.h: Likewise. * gimple-range-tests.cc: Likewise. * gimple-range.h: Likewise. * gimple-ssa-evrp.cc: Likewise. * input.cc: Likewise. * json.h: Likewise. * read-rtl-function.cc: Likewise. * tree-complex.cc: Likewise. * tree-diagnostic-path.cc: Likewise. * tree-ssa-ccp.cc: Likewise. * tree-ssa-copy.cc: Likewise. * tree-vrp.cc: Likewise. * value-query.h: Likewise. * vr-values.h: Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-05-17Daily bump.GCC Administrator1-0/+80
2022-05-16analyzer: implement four new warnings for <stdarg.h> misuses [PR105103]David Malcolm18-21/+1402
This patch adds support to the analyzer for checking usage of <stdarg.h>, with four new warnings. It adds: (a) a state-machine for tracking "started" and "ended" states on va_list instances, implementing two new warnings: -Wanalyzer-va-list-leak for complaining about missing va_end after a va_start or va_copy -Wanalyzer-va-list-use-after-va-end: for complaining about va_arg or va_copy used on a va_list that's had va_end called on it (b) interprocedural tracking of variadic parameters, tracking symbolic values, implementing two new warnings: -Wanalyzer-va-arg-type-mismatch for type-checking va_arg usage against the types of the parameters that were actually passed to the variadic call -Wanalyzer-va-list-exhausted for complaining if va_arg is used too many times on a va_list Here's an LTO example of a type mismatch in a variadic call that straddles two source files: stdarg-lto-1-a.c: In function 'called_by_test_type_mismatch_1': stdarg-lto-1-a.c:19:7: warning: 'va_arg' expected 'const char *' but received 'int' for variadic argument 1 of 'ap' [-Wanalyzer-va-arg-type-mismatch] 19 | str = va_arg (ap, const char *); | ^ 'test_type_mismatch_1': events 1-2 | |stdarg-lto-1-b.c:3:6: | 3 | void test_type_mismatch_1 (void) | | ^ | | | | | (1) entry to 'test_type_mismatch_1' | 4 | { | 5 | called_by_test_type_mismatch_1 (42, 1066); | | ~ | | | | | (2) calling 'called_by_test_type_mismatch_1' from 'test_type_mismatch_1' with 1 variadic argument | +--> 'called_by_test_type_mismatch_1': events 3-4 | |stdarg-lto-1-a.c:12:1: | 12 | called_by_test_type_mismatch_1 (int placeholder, ...) | | ^ | | | | | (3) entry to 'called_by_test_type_mismatch_1' |...... | 19 | str = va_arg (ap, const char *); | | ~ | | | | | (4) 'va_arg' expected 'const char *' but received 'int' for variadic argument 1 of 'ap' | gcc/ChangeLog: PR analyzer/105103 * Makefile.in (ANALYZER_OBJS): Add analyzer/varargs.o. * doc/invoke.texi: Add -Wanalyzer-va-arg-type-mismatch, -Wanalyzer-va-list-exhausted, -Wanalyzer-va-list-leak, and -Wanalyzer-va-list-use-after-va-end. gcc/analyzer/ChangeLog: PR analyzer/105103 * analyzer.cc (make_label_text_n): New. * analyzer.h (class var_arg_region): New forward decl. (make_label_text_n): New decl. * analyzer.opt (Wanalyzer-va-arg-type-mismatch): New option. (Wanalyzer-va-list-exhausted): New option. (Wanalyzer-va-list-leak): New option. (Wanalyzer-va-list-use-after-va-end): New option. * checker-path.cc (call_event::get_desc): Split out decl access into.. (call_event::get_caller_fndecl): ...this new function and... (call_event::get_callee_fndecl): ...this new function. * checker-path.h (call_event::get_desc): Drop "FINAL". (call_event::get_caller_fndecl): New decl. (call_event::get_callee_fndecl): New decl. (class call_event): Make fields protected. * diagnostic-manager.cc (null_assignment_sm_context::warn): New overload. (null_assignment_sm_context::get_new_program_state): New. (diagnostic_manager::add_events_for_superedge): Move case SUPEREDGE_CALL to a new pending_diagnostic::add_call_event vfunc. * engine.cc (impl_sm_context::warn): Implement new override. (impl_sm_context::get_new_program_state): New. * pending-diagnostic.cc: Include "analyzer/diagnostic-manager.h", "cpplib.h", "digraph.h", "ordered-hash-map.h", "cfg.h", "basic-block.h", "gimple.h", "gimple-iterator.h", "cgraph.h" "analyzer/supergraph.h", "analyzer/program-state.h", "alloc-pool.h", "fibonacci_heap.h", "shortest-paths.h", "sbitmap.h", "analyzer/exploded-graph.h", "diagnostic-path.h", and "analyzer/checker-path.h". (ht_ident_eq): New. (fixup_location_in_macro_p): New. (pending_diagnostic::fixup_location): New. (pending_diagnostic::add_call_event): New. * pending-diagnostic.h (pending_diagnostic::fixup_location): Drop no-op inline implementation in favor of the more complex implementation above. (pending_diagnostic::add_call_event): New vfunc. * region-model-impl-calls.cc: Include "analyzer/sm.h", "diagnostic-path.h", and "analyzer/pending-diagnostic.h". * region-model-manager.cc (region_model_manager::get_var_arg_region): New. (region_model_manager::log_stats): Log m_var_arg_regions. * region-model.cc (region_model::on_call_pre): Handle IFN_VA_ARG, BUILT_IN_VA_START, and BUILT_IN_VA_COPY. (region_model::on_call_post): Handle BUILT_IN_VA_END. (region_model::get_representative_path_var_1): Handle RK_VAR_ARG. (region_model::push_frame): Push variadic arguments. * region-model.h (region_model_manager::get_var_arg_region): New decl. (region_model_manager::m_var_arg_regions): New field. (region_model::impl_call_va_start): New decl. (region_model::impl_call_va_copy): New decl. (region_model::impl_call_va_arg): New decl. (region_model::impl_call_va_end): New decl. * region.cc (alloca_region::dump_to_pp): Dump the id. (var_arg_region::dump_to_pp): New. (var_arg_region::get_frame_region): New. * region.h (enum region_kind): Add RK_VAR_ARG. (region::dyn_cast_var_arg_region): New. (class var_arg_region): New. (is_a_helper <const var_arg_region *>::test): New. (struct default_hash_traits<var_arg_region::key_t>): New. * sm.cc (make_checkers): Call make_va_list_state_machine. * sm.h (sm_context::warn): New vfunc. (sm_context::get_old_svalue): Drop unused decl. (sm_context::get_new_program_state): New vfunc. (make_va_list_state_machine): New decl. * varargs.cc: New file. gcc/testsuite/ChangeLog: PR analyzer/105103 * gcc.dg/analyzer/stdarg-1.c: New test. * gcc.dg/analyzer/stdarg-2.c: New test. * gcc.dg/analyzer/stdarg-fmtstring-1.c: New test. * gcc.dg/analyzer/stdarg-lto-1-a.c: New test. * gcc.dg/analyzer/stdarg-lto-1-b.c: New test. * gcc.dg/analyzer/stdarg-lto-1.h: New test. * gcc.dg/analyzer/stdarg-sentinel-1.c: New test. * gcc.dg/analyzer/stdarg-types-1.c: New test. * gcc.dg/analyzer/stdarg-types-2.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-05-16Use more ARRAY_SIZE.Martin Liska5-8/+5
gcc/ada/ChangeLog: * locales.c (iso_639_1_to_639_3): Use ARRAY_SIZE. (language_name_to_639_3): Likewise. (country_name_to_3166): Likewise. gcc/analyzer/ChangeLog: * engine.cc (exploded_node::get_dot_fillcolor): Use ARRAY_SIZE. * function-set.cc (test_stdio_example): Likewise. * sm-file.cc (get_file_using_fns): Likewise. * sm-malloc.cc (malloc_state_machine::unaffected_by_call_p): Likewise. * sm-signal.cc (get_async_signal_unsafe_fns): Likewise. gcc/ChangeLog: * attribs.cc (diag_attr_exclusions): Use ARRAY_SIZE. (decls_mismatched_attributes): Likewise. * builtins.cc (c_strlen): Likewise. * cfg.cc (DEF_BASIC_BLOCK_FLAG): Likewise. * common/config/aarch64/aarch64-common.cc (aarch64_option_init_struct): Likewise. * config/aarch64/aarch64-builtins.cc (aarch64_lookup_simd_builtin_type): Likewise. (aarch64_init_simd_builtin_types): Likewise. (aarch64_init_builtin_rsqrt): Likewise. * config/aarch64/aarch64.cc (is_madd_op): Likewise. * config/arm/arm-builtins.cc (arm_lookup_simd_builtin_type): Likewise. (arm_init_simd_builtin_types): Likewise. * config/avr/gen-avr-mmcu-texi.cc (mcus[ARRAY_SIZE): Likewise. (c_prefix): Likewise. (main): Likewise. * config/c6x/c6x.cc (N_SAVE_ORDER): Likewise. * config/darwin-c.cc (darwin_register_frameworks): Likewise. * config/gcn/mkoffload.cc (process_obj): Likewise. * config/i386/i386-builtins.cc (get_builtin_code_for_version): Likewise. (fold_builtin_cpu): Likewise. * config/m32c/m32c.cc (PUSHM_N): Likewise. * config/nvptx/mkoffload.cc (process): Likewise. * config/rs6000/driver-rs6000.cc (host_detect_local_cpu): Likewise. * config/s390/s390.cc (NR_C_MODES): Likewise. * config/tilepro/gen-mul-tables.cc (find_sequences): Likewise. (create_insn_code_compression_table): Likewise. * config/vms/vms.cc (NBR_CRTL_NAMES): Likewise. * diagnostic-format-json.cc (json_from_expanded_location): Likewise. * dwarf2out.cc (ARRAY_SIZE): Likewise. * genhooks.cc (emit_documentation): Likewise. (emit_init_macros): Likewise. * gimple-ssa-sprintf.cc (format_floating): Likewise. * gimple-ssa-warn-access.cc (memmodel_name): Likewise. * godump.cc (keyword_hash_init): Likewise. * hash-table.cc (hash_table_higher_prime_index): Likewise. * input.cc (for_each_line_table_case): Likewise. * ipa-free-lang-data.cc (free_lang_data): Likewise. * ipa-inline.cc (sanitize_attrs_match_for_inline_p): Likewise. * optc-save-gen.awk: Likewise. * spellcheck.cc (test_metric_conditions): Likewise. * tree-vect-slp-patterns.cc (sizeof): Likewise. (ARRAY_SIZE): Likewise. * tree.cc (build_common_tree_nodes): Likewise. gcc/c-family/ChangeLog: * c-common.cc (ARRAY_SIZE): Use ARRAY_SIZE. (c_common_nodes_and_builtins): Likewise. * c-format.cc (check_tokens): Likewise. (check_plain): Likewise. * c-pragma.cc (c_pp_lookup_pragma): Likewise. (init_pragma): Likewise. * known-headers.cc (get_string_macro_hint): Likewise. (get_stdlib_header_for_name): Likewise. * c-attribs.cc: Likewise. gcc/c/ChangeLog: * c-decl.cc (match_builtin_function_types): Use ARRAY_SIZE. gcc/cp/ChangeLog: * module.cc (depset::entity_kind_name): Use ARRAY_SIZE. * name-lookup.cc (get_std_name_hint): Likewise. * parser.cc (cp_parser_new): Likewise. gcc/fortran/ChangeLog: * frontend-passes.cc (gfc_code_walker): Use ARRAY_SIZE. * openmp.cc (gfc_match_omp_context_selector_specification): Likewise. * trans-intrinsic.cc (conv_intrinsic_ieee_builtin): Likewise. * trans-types.cc (gfc_get_array_descr_info): Likewise. gcc/jit/ChangeLog: * jit-builtins.cc (find_builtin_by_name): Use ARRAY_SIZE. (get_string_for_type_id): Likewise. * jit-recording.cc (recording::context::context): Likewise. gcc/lto/ChangeLog: * lto-common.cc (lto_resolution_read): Use ARRAY_SIZE. * lto-lang.cc (lto_init): Likewise.
2022-05-14Daily bump.GCC Administrator1-0/+4
2022-05-13Make gimple_build main workers more flexibleRichard Biener1-2/+2
The following makes the main gimple_build API take a gimple_stmt_iterator, whether to insert before or after and an iterator update argument to make it more convenient to use in certain situations (see the tree-vect-generic.cc hunks for an example). It also makes the case we insert into the IL somewhat distinct from inserting into a standalone sequence in that it simplifies built expressions the same way as inserting and calling fold_stmt (..., follow_all_ssa_edges) would. When inserting into a standalone sequence we restrict simplification to defs within the currently building sequence. The patch only amends the tree_code gimple_build API, I will followup with converting the rest as well. The patch got larger than intended because the template forwarders now use gsi_last which introduces a dependency on gimple-iterator.h requiring mass #include re-org across the tree. There are two frontend specific files including gimple-fold.h just for some padding clearing stuff - I've removed the include and instead moved the declarations to fold-const.h (but not the implementations). Otherwise I'd have to include half of the middle-end headers in those files which I didn't much like. 2022-05-12 Richard Biener <rguenther@suse.de> gcc/cp/ * constexpr.cc: Remove gimple-fold.h include. gcc/c-family/ * c-omp.cc: Remove gimple-fold.h include. gcc/analyzer/ * supergraph.cc: Re-order gimple-fold.h include. gcc/ * gimple-fold.cc (gimple_build): Adjust for new main API. * gimple-fold.h (gimple_build): New main APIs with iterator, insert direction and iterator update. (gimple_build): New forwarder template. (clear_padding_type_may_have_padding_p): Remove. (clear_type_padding_in_mask): Likewise. (arith_overflowed_p): Likewise. * fold-const.h (clear_padding_type_may_have_padding_p): Declare. (clear_type_padding_in_mask): Likewise. (arith_overflowed_p): Likewise. * tree-vect-generic.cc (gimplify_build3): Use main gimple_build API. (gimplify_build2): Likewise. (gimplify_build1): Likewise. * ubsan.cc (ubsan_expand_ptr_ifn): Likewise, avoid extra compare stmt. * gengtype.cc (open_base_files): Re-order includes. * builtins.cc: Re-order gimple-fold.h include. * calls.cc: Likewise. * cgraphbuild.cc: Likewise. * cgraphunit.cc: Likewise. * config/rs6000/rs6000-builtin.cc: Likewise. * config/rs6000/rs6000-call.cc: Likewise. * config/rs6000/rs6000.cc: Likewise. * config/s390/s390.cc: Likewise. * expr.cc: Likewise. * fold-const.cc: Likewise. * function-tests.cc: Likewise. * gimple-match-head.cc: Likewise. * gimple-range-fold.cc: Likewise. * gimple-ssa-evrp-analyze.cc: Likewise. * gimple-ssa-evrp.cc: Likewise. * gimple-ssa-sprintf.cc: Likewise. * gimple-ssa-warn-access.cc: Likewise. * gimplify.cc: Likewise. * graphite-isl-ast-to-gimple.cc: Likewise. * ipa-cp.cc: Likewise. * ipa-devirt.cc: Likewise. * ipa-prop.cc: Likewise. * omp-low.cc: Likewise. * pointer-query.cc: Likewise. * range-op.cc: Likewise. * tree-cfg.cc: Likewise. * tree-if-conv.cc: Likewise. * tree-inline.cc: Likewise. * tree-object-size.cc: Likewise. * tree-ssa-ccp.cc: Likewise. * tree-ssa-dom.cc: Likewise. * tree-ssa-forwprop.cc: Likewise. * tree-ssa-ifcombine.cc: Likewise. * tree-ssa-loop-ivcanon.cc: Likewise. * tree-ssa-math-opts.cc: Likewise. * tree-ssa-pre.cc: Likewise. * tree-ssa-propagate.cc: Likewise. * tree-ssa-reassoc.cc: Likewise. * tree-ssa-sccvn.cc: Likewise. * tree-ssa-strlen.cc: Likewise. * tree-ssa.cc: Likewise. * value-pointer-equiv.cc: Likewise. * vr-values.cc: Likewise. gcc/testsuite/ * gcc.dg/plugin/diagnostic_group_plugin.c: Reorder or remove gimple-fold.h include. * gcc.dg/plugin/diagnostic_plugin_show_trees.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_inlining.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_metadata.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_paths.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_string_literals.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c: Likewise. * gcc.dg/plugin/finish_unit_plugin.c: Likewise. * gcc.dg/plugin/ggcplug.c: Likewise. * gcc.dg/plugin/must_tail_call_plugin.c: Likewise. * gcc.dg/plugin/one_time_plugin.c: Likewise. * gcc.dg/plugin/selfassign.c: Likewise. * gcc.dg/plugin/start_unit_plugin.c: Likewise. * g++.dg/plugin/selfassign.c: Likewise.
2022-05-12Daily bump.GCC Administrator1-0/+18
2022-05-11analyzer: fix memory leaksDavid Malcolm4-18/+39
These leaks all relate to logging within -fdump-analyzer[-stderr] or are one-time leaks; seen with valgrind. gcc/analyzer/ChangeLog: * checker-path.cc (state_change_event::get_desc): Call maybe_free on label_text temporaries. * diagnostic-manager.cc (diagnostic_manager::prune_for_sm_diagnostic): Likewise. * engine.cc (exploded_graph::~exploded_graph): Fix leak of m_per_point_data and m_per_call_string_data values. Simplify cleanup of m_per_function_stats and m_per_point_data values. (feasibility_state::maybe_update_for_edge): Fix leak of result of superedge::get_description. * region-model-manager.cc (region_model_manager::~region_model_manager): Move cleanup of m_setjmp_values to match the ordering of the fields within region_model_manager. Fix leak of values within m_repeated_values_map, m_bits_within_values_map, m_asm_output_values_map, and m_const_fn_result_values_map. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-04-29Daily bump.GCC Administrator1-0/+23
2022-04-28analyzer: handle repeated accesses after init of unknown size [PR105285]David Malcolm1-0/+12
PR analyzer/105285 reports a false positive from -Wanalyzer-null-dereference on git.git's reftable/reader.c. A reduced version of the problem can be seen in test_1a of gcc.dg/analyzer/symbolic-12.c in the following: void test_1a (void *p, unsigned next_off) { struct st_1 *r = p; external_fn(); if (next_off >= r->size) return; if (next_off >= r->size) /* We should have already returned if this is the case. */ __analyzer_dump_path (); /* { dg-bogus "path" } */ } where the analyzer erroneously considers this path, where (next_off >= r->size) is both false and then true: symbolic-12.c: In function ‘test_1a’: symbolic-12.c:22:5: note: path 22 | __analyzer_dump_path (); /* { dg-bogus "path" } */ | ^~~~~~~~~~~~~~~~~~~~~~~ ‘test_1a’: events 1-5 | | 17 | if (next_off >= r->size) | | ^ | | | | | (1) following ‘false’ branch... |...... | 20 | if (next_off >= r->size) | | ~ ~~~~~~~ | | | | | | | (2) ...to here | | (3) following ‘true’ branch... | 21 | /* We should have already returned if this is the case. */ | 22 | __analyzer_dump_path (); /* { dg-bogus "path" } */ | | ~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (4) ...to here | | (5) here | The root cause is that, at the call to the external function, the analyzer considers the cluster for *p to have been touched, binding it to a conjured_svalue, but because p is void * no particular size is known for the write, and so the cluster is bound using a symbolic key covering the base region. Later, the accesses to r->size are handled by binding_cluster::get_any_binding, but binding_cluster::get_binding fails to find a match for the concrete field lookup, due to the key for the binding being symbolic, and reaching this code: 1522 /* If this cluster has been touched by a symbolic write, then the content 1523 of any subregion not currently specifically bound is "UNKNOWN". */ 1524 if (m_touched) 1525 { 1526 region_model_manager *rmm_mgr = mgr->get_svalue_manager (); 1527 return rmm_mgr->get_or_create_unknown_svalue (reg->get_type ()); 1528 } Hence each access to r->size is an unknown svalue, and thus the condition (next_off >= r->size) isn't tracked, leading to the path with contradictory conditions being treated as satisfiable. In the original reproducer in git's reftable/reader.c, the call to the external fn is: reftable_record_type(rec) which is considered to possibly write to *rec, which is *tab, where tab is the void * argument to reftable_reader_seek_void, and thus after the call to reftable_record_type some arbitrary amount of *rec could have been written to. This patch fixes things by detecting the "this cluster has been 'filled' with a conjured value of unknown size" case, and handling get_any_binding on it by returning a sub_svalue of the conjured_svalue, so that repeated accesses to r->size give the same symbolic value, so that the constraint manager rejects the bogus execution path, fixing the false positive. gcc/analyzer/ChangeLog: PR analyzer/105285 * store.cc (binding_cluster::get_any_binding): Handle accessing sub_svalues of clusters where the base region has a symbolic binding. gcc/testsuite/ChangeLog: PR analyzer/105285 * gcc.dg/analyzer/symbolic-12.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-04-28analyzer: add .fpath.txt dumps to -fdump-analyzer-feasibilityDavid Malcolm7-1/+110
I found this extension to -fdump-analyzer-feasibility very helpful when debugging PR analyzer/105285. gcc/analyzer/ChangeLog: * diagnostic-manager.cc (epath_finder::process_worklist_item): Call dump_feasible_path when a path that reaches the the target enode is found. (epath_finder::dump_feasible_path): New. * engine.cc (feasibility_state::dump_to_pp): New. * exploded-graph.h (feasibility_state::dump_to_pp): New decl. * feasible-graph.cc (feasible_graph::dump_feasible_path): New. * feasible-graph.h (feasible_graph::dump_feasible_path): New decls. * program-point.cc (function_point::print): Fix missing trailing newlines. * program-point.h (program_point::print_source_line): Remove unimplemented decl. gcc/ChangeLog: * doc/invoke.texi (-fdump-analyzer-feasibility): Mention the fpath.txt output. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-04-26Daily bump.GCC Administrator1-0/+11
2022-04-25analyzer: fix ICEs on complex constants [PR105365,105366]David Malcolm1-9/+21
gcc/analyzer/ChangeLog: PR analyzer/105365 PR analyzer/105366 * svalue.cc (cmp_cst): Rename to... (cmp_csts_same_type): ...this. Convert all recursive calls to calls to... (cmp_csts_and_types): ....this new function. (svalue::cmp_ptr): Update for renaming of cmp_cst gcc/testsuite/ChangeLog: PR analyzer/105365 PR analyzer/105366 * gcc.dg/analyzer/pr105365.c: New test. * gcc.dg/analyzer/pr105366.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-04-15Daily bump.GCC Administrator1-0/+15
2022-04-14analyzer: fix escaping of pointer arithmetic [PR105264]David Malcolm3-6/+46
PR analyzer/105264 reports that the analyzer can fail to treat (PTR + IDX) and PTR[IDX] as referring to the same memory under some situations. There are various ways in which this can happen when IDX is a symbolic value, due to having several ways in which such memory regions can be referred to symbolically. I attempted to fix this by being smarter when folding svalues and regions, but this fix seems too fiddly to attempt in stage 4. Instead, this less ambitious patch fixes a false positive from -Wanalyzer-use-of-uninitialized-value by making the analyzer's escape analysis smarter, so that it treats *PTR as escaping when (PTR + OFFSET) is passed to an external function, and thus it treats *PTR as possibly-initialized (the "passing &PTR[IDX]" case was already working). gcc/analyzer/ChangeLog: PR analyzer/105264 * region-model-reachability.cc (reachable_regions::handle_parm): Use maybe_get_deref_base_region rather than just region_svalue, to handle pointer arithmetic also. * svalue.cc (svalue::maybe_get_deref_base_region): New. * svalue.h (svalue::maybe_get_deref_base_region): New decl. gcc/testsuite/ChangeLog: PR analyzer/105264 * gcc.dg/analyzer/torture/symbolic-10.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-04-14analyzer: fix ICE comparing VECTOR_CSTs [PR105252]David Malcolm1-3/+10
gcc/analyzer/ChangeLog: PR analyzer/105252 * svalue.cc (cmp_cst): When comparing VECTOR_CSTs, compare the types of the encoded elements before calling cmp_cst on them. gcc/testsuite/ChangeLog: PR analyzer/105252 * gcc.dg/analyzer/pr105252.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-04-10Daily bump.GCC Administrator1-0/+18
2022-04-09analyzer: fix folding of regions involving unknown ptrs [PR103892]David Malcolm3-9/+41
PR analyzer/103892 reports a false positive from -Wanalyzer-double-free. The root cause is the analyzer failing to properly handle "unknown" symbolic regions, and thus confusing two different expressions. Specifically, the analyzer eventually hits the complexity limit for symbolic values, and starts using an "unknown" svalue for a pointer. The analyzer uses symbolic_region(unknown_svalue([of ptr type])) i.e. (*UNKNOWN_PTR) in a few places to mean "we have an lvalue, but we're not going to attempt to track what it is anymore". "Unknown" should probably be renamed to "unknowable"; in theory, any operation on such an unknown svalue should be also an unknown svalue. The issue is that in various places where we create child regions, we were failing to check for the parent region being (*UNKNOWN_PTR), and so were erroneously creating regions based on (*UNKNOWN_PTR), such as *(UNKNOWN_PTR + OFFSET). The state-machine handling was erroneously allowing e.g. INITIAL_VALUE (*(UNKNOWN_PTR + OFFSET)) to have state, and thus we could record that such a value had had "free" called on it, and thus eventually false report a double-free when a different expression incorrectly "simplified" to the same expression. This patch fixes things by checking when creating the various kinds of child region for (*UNKNOWN_PTR) as the parent region, and simply returning another (*UNKNOWN_PTR) for such child regions (using the appropriate type). Doing so fixes the false positive, and also fixes a state explosion on this testcase, as the states at the program points more rapidly reach a fixed point where everything is unknown. I checked for other cases that no longer needed -Wno-analyzer-too-complex; the only other one seems to be gcc.dg/analyzer/pr96841.c, but that seems to already have become redundant at some point before this patch. gcc/analyzer/ChangeLog: PR analyzer/103892 * region-model-manager.cc (region_model_manager::get_unknown_symbolic_region): New, extracted from... (region_model_manager::get_field_region): ...here. (region_model_manager::get_element_region): Use it here. (region_model_manager::get_offset_region): Likewise. (region_model_manager::get_sized_region): Likewise. (region_model_manager::get_cast_region): Likewise. (region_model_manager::get_bit_range): Likewise. * region-model.h (region_model_manager::get_unknown_symbolic_region): New decl. * region.cc (symbolic_region::symbolic_region): Handle sval_ptr having NULL type. (symbolic_region::dump_to_pp): Handle having NULL type. gcc/testsuite/ChangeLog: PR analyzer/103892 * gcc.dg/analyzer/pr103892.c: New test. * gcc.dg/analyzer/pr96841.c: Drop redundant -Wno-analyzer-too-complex. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-04-08Daily bump.GCC Administrator1-0/+30
2022-04-07analyzer: fix leak false +ve with symbolic writes [PR102208]David Malcolm2-24/+98
PR analyzer/102208 reports false positives from -Wanalyzer-malloc-leak. The root cause is the analyzer getting confused about symbolic writes that could alias a pointer referencing a malloced buffer. struct st { void *ptr; int arr[10]; }; struct st test (int idx) { struct st s; s.ptr = __builtin_malloc (1024); /* (1) */ s.arr[idx] = 42; /* (2) */ return s; } When removing overlapping bindings at (2), store::remove_overlapping_bindings was failing to pass on the uncertainty_t *, and thus when clobbering the binding of s.ptr, the heap-allocated pointer was not being added to the set of maybe-bound svalues, and thus being treated as leaking. This patch fixes this, so that s.ptr from (1) is treated as maybe-bound after the write at (2), fixing the leak false postive. Doing so requires the store to be smarter about how clobbering happens with various combinations of concrete keys and symbolic keys within concrete clusters and symbolic clusters, so that we don't lose warnings about definite leaks. gcc/analyzer/ChangeLog: PR analyzer/102208 * store.cc (binding_map::remove_overlapping_bindings): Add "always_overlap" param, using it to generalize to the case where we want to remove all bindings. Update "uncertainty" logic to only record maybe-bound values for cases where there is a symbolic write involved. (binding_cluster::mark_region_as_unknown): Split param "reg" into "reg_to_bind" and "reg_for_overlap". (binding_cluster::maybe_get_compound_binding): Pass "false" to binding_map::remove_overlapping_bindings new "always_overlap" param. (binding_cluster::remove_overlapping_bindings): Determine "always_overlap" and pass it to binding_map::remove_overlapping_bindings. (store::set_value): Pass uncertainty to remove_overlapping_bindings call. Update for new param of binding_cluster::mark_region_as_unknown, passing both the base region of the iter_cluster, and the lhs_reg. (store::mark_region_as_unknown): Update for new param of binding_cluster::mark_region_as_unknown, passing "reg" for both. (store::remove_overlapping_bindings): Add param "uncertainty", and pass it on to call to binding_cluster::remove_overlapping_bindings. * store.h (binding_map::remove_overlapping_bindings): Add "always_overlap" param. (binding_cluster::mark_region_as_unknown): Split param "reg" into "reg_to_bind" and "reg_for_overlap". (store::remove_overlapping_bindings): Add param "uncertainty". gcc/testsuite/ChangeLog: PR analyzer/102208 * gcc.dg/analyzer/symbolic-9.c: New test. * gcc.dg/analyzer/torture/leak-pr102308-1.c: New test. * gcc.dg/analyzer/torture/leak-pr102308-2.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-30Daily bump.GCC Administrator1-0/+52
2022-03-29analyzer: skip constant pool in -fdump-analyzer-untracked [PR testsuite/105085]David Malcolm1-0/+7
In r12-7809-g5f6197d7c197f9 I added -fdump-analyzer-untracked as support for DejaGnu testing of an optimization of -fanalyzer, PR analyzer/104954. PR testsuite/105085 notes testsuite failures of the form: FAIL: gcc.dg/analyzer/untracked-1.c (test for excess errors) Excess errors: cc1: warning: track '*.LC1': yes where these warnings are emitted on some targets where the test causes labelled constants to be created in the constant pool. We probably ought not to be tracking the values of such decls in the store, given that they're meant to be constant, and I attempted various fixes to make the "should we track this decl" logic smarter, but given that we're in stage 4, the simplest fix seems to be for -fdump-analyzer-untracked to skip such decls in its output, to minimize test output differences between targets. gcc/analyzer/ChangeLog: PR testsuite/105085 * region-model-manager.cc (dump_untracked_region): Skip decls in the constant pool. gcc/testsuite/ChangeLog: PR testsuite/105085 * gcc.dg/analyzer/untracked-1.c: Add further test coverage. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-28analyzer: ensure that we purge state when reusing a conjured_svalue [PR105087]David Malcolm9-27/+85
PR analyzer/105087 describes a false positive from -Wanalyzer-double-free in which the analyzer erroneously considers two successive inlined vasprintf calls to have allocated the same pointer. The root cause is that the result written back from vasprintf is a conjured_svalue, and that we normally purge state when reusing a conjured_svalue, but various places in the code were calling region_model_manager::get_or_create_conjured_svalue but failing to then call region_model::purge_state_involving on the result. This patch fixes things by moving responsibility for calling region_model::purge_state_involving into region_model_manager::get_or_create_conjured_svalue, so that it is always called when reusing a conjured_svalue, fixing the false positive. gcc/analyzer/ChangeLog: PR analyzer/105087 * analyzer.h (class conjured_purge): New forward decl. * region-model-asm.cc (region_model::on_asm_stmt): Add conjured_purge param to calls binding_cluster::on_asm and region_model_manager::get_or_create_conjured_svalue. * region-model-impl-calls.cc (call_details::get_or_create_conjured_svalue): Likewise for call to region_model_manager::get_or_create_conjured_svalue. (region_model::impl_call_fgets): Remove call to region_model::purge_state_involving, as this is now done implicitly by call_details::get_or_create_conjured_svalue. (region_model::impl_call_fread): Likewise. (region_model::impl_call_strchr): Pass conjured_purge param to call to region_model_manager::get_or_create_conjured_svalue. * region-model-manager.cc (conjured_purge::purge): New. (region_model_manager::get_or_create_conjured_svalue): Add param "p". Use it to purge state when reusing an existing conjured_svalue. * region-model.cc (region_model::on_call_pre): Replace call to region_model::purge_state_involving with passing conjured_purge to region_model_manager::get_or_create_conjured_svalue. (region_model::handle_unrecognized_call): Pass conjured_purge to store::on_unknown_fncall. * region-model.h (region_model_manager::get_or_create_conjured_svalue): Add param "p". * store.cc (binding_cluster::on_unknown_fncall): Likewise. Pass it on to region_model_manager::get_or_create_conjured_svalue. (binding_cluster::on_asm): Likewise. (store::on_unknown_fncall): Add param "p" and pass it on to binding_cluster::on_unknown_fncall. * store.h (binding_cluster::on_unknown_fncall): Add param p. (binding_cluster::on_asm): Likewise. (store::on_unknown_fncall): Likewise. * svalue.h (class conjured_purge): New. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/pr105087-1.c: New test. * gcc.dg/analyzer/pr105087-2.c: New test. * gcc.dg/analyzer/vasprintf-1.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-28analyzer: fix ICE with incorrect lookup of cgraph node [PR105074]David Malcolm1-6/+7
gcc/analyzer/ChangeLog: PR analyzer/105074 * region.cc (ipa_ref_requires_tracking): Drop "context_fndecl", instead using the ref->referring to get the cgraph node of the caller. (symnode_requires_tracking_p): Likewise. gcc/testsuite/ChangeLog: PR analyzer/105074 * gcc.dg/analyzer/pr105074.c: New test. * gcc.dg/analyzer/untracked-1.c (extern_fn_char_ptr): New decl. (test_13): New. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-27Daily bump.GCC Administrator1-0/+9
2022-03-26analyzer: fix ICE on memset of untracked region [PR105057]David Malcolm1-4/+13
In r12-7809-g5f6197d7c197f9d2b7fb2e1a19dac39a023755e8 I added an optimization to avoid tracking the state of certain memory regions in the store. Unfortunately, I didn't cover every way in which store::get_or_create_cluster can be called for a base region, leading to assertion failure ICEs in -fanalyzer on certain function calls with certain params. I've worked through all uses of store::get_or_create_cluster and found four places where the assertion could fire. This patch fixes them, and adds regression tests where possible. gcc/analyzer/ChangeLog: PR analyzer/105057 * store.cc (binding_cluster::make_unknown_relative_to): Reject attempts to create a cluster for untracked base regions. (store::set_value): Likewise. (store::fill_region): Likewise. (store::mark_region_as_unknown): Likewise. gcc/testsuite/ChangeLog: PR analyzer/105057 * gcc.dg/analyzer/fread-2.c: New test, as a regression test for ICE in store::set_value on untracked base region. * gcc.dg/analyzer/memset-2.c: Likewise, for ICE in store::fill_region. * gcc.dg/analyzer/strcpy-2.c: Likewise, for ICE in store::mark_region_as_unknown. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-26Daily bump.GCC Administrator1-0/+28
2022-03-24analyzer: add region::tracked_p to optimize state objects [PR104954]David Malcolm8-4/+167
PR analyzer/104954 tracks that -fanalyzer was taking a very long time on a particular source file in the Linux kernel: drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c One issue occurs with the repeated use of dynamic debug lines e.g. via the DC_LOG_BANDWIDTH_CALCS macro, such as in print_bw_calcs_dceip in drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h: DC_LOG_BANDWIDTH_CALCS("#####################################################################"); DC_LOG_BANDWIDTH_CALCS("struct bw_calcs_dceip"); DC_LOG_BANDWIDTH_CALCS("#####################################################################"); [...snip dozens of lines...] DC_LOG_BANDWIDTH_CALCS("[bw_fixed] dmif_request_buffer_size: %d", bw_fixed_to_int(dceip->dmif_request_buffer_size)); When this is configured to use __dynamic_pr_debug, each of these becomes code like: do { static struct _ddebug __attribute__((__aligned__(8))) __attribute__((__section__("__dyndbg"))) __UNIQUE_ID_ddebug277 = { [...snip...] }; if (arch_static_branch(&__UNIQUE_ID_ddebug277.key, false)) __dynamic_pr_debug(&__UNIQUE_ID_ddebug277, [...the message...]); } while (0); The analyzer was naively seeing each call to __dynamic_pr_debug, noting that the __UNIQUE_ID_nnnn object escapes. At each call, as successive __UNIQUE_ID_nnnn object escapes, there are N escaped objects, and thus N need clobbering, and so we have O(N^2) clobbering of escaped objects overall, leading to huge amounts of pointless work: print_bw_calcs_data has 225 uses of DC_LOG_BANDWIDTH_CALCS, many of which are in loops. This patch adds a way to identify declarations that aren't interesting to the analyzer, so that we don't attempt to create binding_clusters for them (i.e. we don't store any state for them in our state objects). This is implemented by adding a new region::tracked_p, implemented for declarations by walking the existing IPA data the first time the analyzer sees a declaration, setting it to false for global vars that have no loads/stores/aliases, and "sufficiently safe" address-of ipa-refs. The patch gives a large speedup of -fanalyzer on the above kernel source file: Before After Total cc1 wallclock time: 180s 36s analyzer wallclock time: 162s 17s % spent in analyzer: 90% 47% gcc/analyzer/ChangeLog: PR analyzer/104954 * analyzer.opt (-fdump-analyzer-untracked): New option. * engine.cc (impl_run_checkers): Handle it. * region-model-asm.cc (region_model::on_asm_stmt): Don't attempt to clobber regions with !tracked_p (). * region-model-manager.cc (dump_untracked_region): New. (region_model_manager::dump_untracked_regions): New. (frame_region::dump_untracked_regions): New. * region-model.h (region_model_manager::dump_untracked_regions): New decl. * region.cc (ipa_ref_requires_tracking): New. (symnode_requires_tracking_p): New. (decl_region::calc_tracked_p): New. * region.h (region::tracked_p): New vfunc. (frame_region::dump_untracked_regions): New decl. (class decl_region): Note that this is also used fo SSA names. (decl_region::decl_region): Initialize m_tracked. (decl_region::tracked_p): New. (decl_region::calc_tracked_p): New decl. (decl_region::m_tracked): New. * store.cc (store::get_or_create_cluster): Assert that we don't try to create clusters for base regions that aren't trackable. (store::mark_as_escaped): Don't mark base regions that we're not tracking. gcc/ChangeLog: PR analyzer/104954 * doc/invoke.texi (Static Analyzer Options): Add -fdump-analyzer-untracked. gcc/testsuite/ChangeLog: PR analyzer/104954 * gcc.dg/analyzer/asm-x86-dyndbg-1.c: New test. * gcc.dg/analyzer/asm-x86-dyndbg-2.c: New test. * gcc.dg/analyzer/many-unused-locals.c: New test. * gcc.dg/analyzer/untracked-1.c: New test. * gcc.dg/analyzer/unused-local-1.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-24Daily bump.GCC Administrator1-0/+50
2022-03-23analyzer: fix accessing wrong stack frame on interprocedural return [PR104979]David Malcolm5-35/+82
PR analyzer/104979 reports a leak false positive when handling an interprocedural return to a caller: LHS = CALL(ARGS); where the LHS is a certain non-trivial compound expression. The root cause is that parts of the LHS were being erroneously evaluated with respect to the stack frame of the called function, rather than tha of the caller. When LHS contained a local variable within the caller as part of certain nested expressions, this local variable was looked for within the called frame, rather than that of the caller. This lookup in the wrong stack frame led to the local variable being treated as uninitialized, and thus the write to LHS was considered as writing to a garbage location, leading to the return value being lost, and thus being considered as a leak. The region_model code uses the analyzer's path_var class to try to extend the tree type with stack depth information. Based on the above, I think that the path_var class is fundamentally broken, but it's used in a few other places in the analyzer, so I don't want to rip it out until the next stage 1. In the meantime, this patch reworks how region_model::pop_frame works so that the destination region for an interprocedural return value is computed after the frame is popped, so that the region_model has the stack frame for the *caller* at that point. Doing so fixes the issue. I attempted a more ambitious fix which moved the storing of the return svalue into the destination region from region_model::pop_region into region_model::update_for_return_gcall, with pop_frame returning the return svalue. Unfortunately, this regressed g++.dg/analyzer/pr93212.C, which returns a pointer into a stale frame. unbind_region_and_descendents and poison_any_pointers_to_descendents are only set up to poison regions with bindings into the stale frame, not individual svalues, and updating that became more invasive than I'm comfortable with in stage 4. The patch also adds assertions to verify that we have the correct function when looking up locals/SSA names in a stack frame. There doesn't seem to be a general-purpose way to get at the function of an SSA name, so the assertions go from SSA name to def-stmt to basic_block, and from there use the analyzer's supergraph to get the function from the basic_block. If there's a simpler way to do this, please let me know. gcc/analyzer/ChangeLog: PR analyzer/104979 * engine.cc (impl_run_checkers): Create the engine after the supergraph, and pass the supergraph to the engine. * region-model.cc (region_model::get_lvalue_1): Pass ctxt to frame_region::get_region_for_local. (region_model::update_for_return_gcall): Pass the lvalue for the result to pop_frame as a tree, rather than as a region. (region_model::pop_frame): Update for above change, determining the destination region after the frame is popped and thus with respect to the caller frame rather than the called frame. Likewise, set the value of the region to the return value after the frame is popped. (engine::engine): Add supergraph pointer. (selftest::test_stack_frames): Set the DECL_CONTECT of PARM_DECLs. (selftest::test_get_representative_path_var): Likewise. (selftest::test_state_merging): Likewise. * region-model.h (region_model::pop_frame): Convert first param from a const region * to a tree. (engine::engine): Add param "sg". (engine::m_sg): New field. * region.cc: Include "analyzer/sm.h" and "analyzer/program-state.h". (frame_region::get_region_for_local): Add "ctxt" param. Add assertions that VAR_DECLs are locals, and that expr is for the correct function. * region.h (frame_region::get_region_for_local): Add "ctxt" param. gcc/testsuite/ChangeLog: PR analyzer/104979 * gcc.dg/analyzer/boxed-malloc-1-29.c: Deleted test, moving the now fixed test_29 to... * gcc.dg/analyzer/boxed-malloc-1.c: ...here. * gcc.dg/analyzer/stale-frame-1.c: Add test coverage. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-23analyzer: use tainted_allocation_size::m_mem_space [PR105017]David Malcolm1-26/+56
gcc/analyzer/ChangeLog: PR analyzer/105017 * sm-taint.cc (taint_diagnostic::subclass_equal_p): Check m_has_bounds as well as m_arg. (tainted_allocation_size::subclass_equal_p): Chain up to base class implementation. Also check m_mem_space. (tainted_allocation_size::emit): Add note showing stack-based vs heap-based allocations. gcc/testsuite/ChangeLog: PR analyzer/105017 * gcc.dg/analyzer/taint-alloc-1.c: Add expected messages relating to heap vs stack. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-23analyzer: fix ICE adding note to disabled diagnostic [PR104997]David Malcolm3-14/+17
gcc/analyzer/ChangeLog: PR analyzer/104997 * diagnostic-manager.cc (diagnostic_manager::add_diagnostic): Convert return type from "void" to "bool", reporting success vs failure to caller, for both overloads. * diagnostic-manager.h (diagnostic_manager::add_diagnostic): Likewise. * engine.cc (impl_region_model_context::warn): Propagate return value from diagnostic_manager::add_diagnostic. gcc/testsuite/ChangeLog: PR analyzer/104997 * gcc.dg/analyzer/write-to-string-literal-4-disabled.c: New test, adapted from write-to-string-literal-4.c. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-19Daily bump.GCC Administrator1-0/+89
2022-03-18analyzer: extend state-purging to locals [PR104943]David Malcolm10-76/+851
The existing analyzer code attempts to purge the state of SSA names where it can in order to minimize the size of program_state instances, and to increase the chances of being able to reuse exploded_node instances whilst exploring the user's code. PR analyzer/104943 identifies that we fail to purge state of local variables, based on behavior seen in PR analyzer/104954 when attempting to profile slow performance of -fanalyzer on a particular file in the Linux kernel, where that testcase has many temporary "boxed" values of structs containing ints, which are never cleaned up, leading to bloat of the program_state instances (specifically, of the store objects). This patch generalizes the state purging from just being on SSA names to also work on local variables. Doing so requires that we detect where addresses to a local variable (or within them) are taken; we assume that once a pointer has been taken, it's not longer safe to purge the value of that decl at any successor point within the function. Doing so speeds up the PR analyzer/104954 Linux kernel analyzer testcase from taking 254 seconds to "just" 186 seconds (and I have a followup patch in development that seems to further reduce this to 37 seconds). The patch may also help with scaling up taint-detection so that it can eventually be turned on by default, but we're not quite there (this is PR analyzer/103533). gcc/analyzer/ChangeLog: PR analyzer/104943 PR analyzer/104954 PR analyzer/103533 * analyzer.h (class state_purge_per_decl): New forward decl. * engine.cc (impl_run_checkers): Pass region_model_manager to state_purge_map ctor. * program-point.cc (function_point::final_stmt_p): New. (function_point::get_next): New. * program-point.h (function_point::final_stmt_p): New decl. (function_point::get_next): New decl. * program-state.cc (program_state::prune_for_point): Generalize to purge local decls as well as SSA names. (program_state::can_purge_base_region_p): New. * program-state.h (program_state::can_purge_base_region_p): New decl. * region-model.cc (struct append_ssa_names_cb_data): Rename to... (struct append_regions_cb_data): ...this. (region_model::get_ssa_name_regions_for_current_frame): Rename to... (region_model::get_regions_for_current_frame): ...this, updating for other renamings. (region_model::append_ssa_names_cb): Rename to... (region_model::append_regions_cb): ...this, and drop the requirement that the subregion be a SSA name. * region-model.h (struct append_ssa_names_cb_data): Rename decl to... (struct append_regions_cb_data): ...this. (region_model::get_ssa_name_regions_for_current_frame): Rename decl to... (region_model::get_regions_for_current_frame): ...this. (region_model::append_ssa_names_cb): Rename decl to... (region_model::append_regions_cb): ...this. * state-purge.cc: Include "tristate.h", "selftest.h", "analyzer/store.h", "analyzer/region-model.h", and "gimple-walk.h". (get_candidate_for_purging): New. (class gimple_op_visitor): New. (my_load_cb): New. (my_store_cb): New. (my_addr_cb): New. (state_purge_map::state_purge_map): Add "mgr" param. Update for renamings. Find uses of local variables. (state_purge_map::~state_purge_map): Update for renaming of m_map to m_ssa_map. Clean up m_decl_map. (state_purge_map::get_or_create_data_for_decl): New. (state_purge_per_ssa_name::state_purge_per_ssa_name): Update for inheriting from state_purge_per_tree. (state_purge_per_ssa_name::add_to_worklist): Likewise. (state_purge_per_decl::state_purge_per_decl): New. (state_purge_per_decl::add_needed_at): New. (state_purge_per_decl::add_pointed_to_at): New. (state_purge_per_decl::process_worklists): New. (state_purge_per_decl::add_to_worklist): New. (same_binding_p): New. (fully_overwrites_p): New. (state_purge_per_decl::process_point_backwards): New. (state_purge_per_decl::process_point_forwards): New. (state_purge_per_decl::needed_at_point_p): New. (state_purge_annotator::print_needed): Generalize to print local decls as well as SSA names. * state-purge.h (class state_purge_map): Update leading comment. (state_purge_map::map_t): Rename to... (state_purge_map::ssa_map_t): ...this. (state_purge_map::iterator): Rename to... (state_purge_map::ssa_iterator): ...this. (state_purge_map::decl_map_t): New typedef. (state_purge_map::decl_iterator): New typedef. (state_purge_map::state_purge_map): Add "mgr" param. (state_purge_map::get_data_for_ssa_name): Update for renaming. (state_purge_map::get_any_data_for_decl): New. (state_purge_map::get_or_create_data_for_decl): New decl. (state_purge_map::begin): Rename to... (state_purge_map::begin_ssas): ...this. (state_purge_map::end): Rename to... (state_purge_map::end_ssa): ...this. (state_purge_map::begin_decls): New. (state_purge_map::end_decls): New. (state_purge_map::m_map): Rename to... (state_purge_map::m_ssa_map): ...this. (state_purge_map::m_decl_map): New field. (class state_purge_per_tree): New class. (class state_purge_per_ssa_name): Inherit from state_purge_per_tree. (state_purge_per_ssa_name::get_function): Move to base class. (state_purge_per_ssa_name::point_set_t): Likewise. (state_purge_per_ssa_name::m_fun): Likewise. (class state_purge_per_decl): New. gcc/testsuite/ChangeLog: PR analyzer/104943 PR analyzer/104954 PR analyzer/103533 * gcc.dg/analyzer/torture/boxed-ptr-1.c: Update expected number of exploded nodes to reflect improvements in state purging. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-18Daily bump.GCC Administrator1-0/+11
2022-03-17analyzer: fixes to -fdump-analyzer-state-purgeDavid Malcolm1-1/+2
gcc/analyzer/ChangeLog: * state-purge.cc (state_purge_annotator::add_node_annotations): Avoid duplicate before-supernode annotations when returning from an interprocedural call. Show after-supernode annotations. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-17analyzer: fix program_point::get_next for PK_BEFORE_STMTDavid Malcolm1-1/+1
gcc/analyzer/ChangeLog: * program-point.cc (program_point::get_next): Fix missing increment of index. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-17Daily bump.GCC Administrator1-0/+72
2022-03-16analyzer: early rejection of disabled warnings [PR104955]David Malcolm11-67/+235
Avoid generating execution paths for warnings that are ultimately rejected due to -Wno-analyzer-* flags. This improves the test case from taking at least several minutes (before I killed it) to taking under a second. This doesn't fix the slowdown seen in PR analyzer/104955 with large numbers of warnings when the warnings are still enabled. gcc/analyzer/ChangeLog: PR analyzer/104955 * diagnostic-manager.cc (get_emission_location): New. (diagnostic_manager::diagnostic_manager): Initialize m_num_disabled_diagnostics. (diagnostic_manager::add_diagnostic): Reject diagnostics that will eventually be rejected due to being disabled. (diagnostic_manager::emit_saved_diagnostics): Log the number of disabled diagnostics. (diagnostic_manager::emit_saved_diagnostic): Split out logic for determining emission location to get_emission_location. * diagnostic-manager.h (diagnostic_manager::m_num_disabled_diagnostics): New field. * engine.cc (stale_jmp_buf::get_controlling_option): New. (stale_jmp_buf::emit): Use it. * pending-diagnostic.h (pending_diagnostic::get_controlling_option): New vfunc. * region-model.cc (poisoned_value_diagnostic::get_controlling_option): New. (poisoned_value_diagnostic::emit): Use it. (shift_count_negative_diagnostic::get_controlling_option): New. (shift_count_negative_diagnostic::emit): Use it. (shift_count_overflow_diagnostic::get_controlling_option): New. (shift_count_overflow_diagnostic::emit): Use it. (dump_path_diagnostic::get_controlling_option): New. (dump_path_diagnostic::emit): Use it. (write_to_const_diagnostic::get_controlling_option): New. (write_to_const_diagnostic::emit): Use it. (write_to_string_literal_diagnostic::get_controlling_option): New. (write_to_string_literal_diagnostic::emit): Use it. * sm-file.cc (double_fclose::get_controlling_option): New. (double_fclose::emit): Use it. (file_leak::get_controlling_option): New. (file_leak::emit): Use it. * sm-malloc.cc (mismatching_deallocation::get_controlling_option): New. (mismatching_deallocation::emit): Use it. (double_free::get_controlling_option): New. (double_free::emit): Use it. (possible_null_deref::get_controlling_option): New. (possible_null_deref::emit): Use it. (possible_null_arg::get_controlling_option): New. (possible_null_arg::emit): Use it. (null_deref::get_controlling_option): New. (null_deref::emit): Use it. (null_arg::get_controlling_option): New. (null_arg::emit): Use it. (use_after_free::get_controlling_option): New. (use_after_free::emit): Use it. (malloc_leak::get_controlling_option): New. (malloc_leak::emit): Use it. (free_of_non_heap::get_controlling_option): New. (free_of_non_heap::emit): Use it. * sm-pattern-test.cc (pattern_match::get_controlling_option): New. (pattern_match::emit): Use it. * sm-sensitive.cc (exposure_through_output_file::get_controlling_option): New. (exposure_through_output_file::emit): Use it. * sm-signal.cc (signal_unsafe_call::get_controlling_option): New. (signal_unsafe_call::emit): Use it. * sm-taint.cc (tainted_array_index::get_controlling_option): New. (tainted_array_index::emit): Use it. (tainted_offset::get_controlling_option): New. (tainted_offset::emit): Use it. (tainted_size::get_controlling_option): New. (tainted_size::emit): Use it. (tainted_divisor::get_controlling_option): New. (tainted_divisor::emit): Use it. (tainted_allocation_size::get_controlling_option): New. (tainted_allocation_size::emit): Use it. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/many-disabled-diagnostics.c: New test. * gcc.dg/plugin/analyzer_gil_plugin.c (gil_diagnostic::get_controlling_option): New. (double_save_thread::emit): Use it. (fncall_without_gil::emit): Likewise. (pyobject_usage_without_gil::emit): Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-16Daily bump.GCC Administrator1-0/+4
2022-03-15analyzer: presize m_cluster_map in store copy ctorDavid Malcolm1-1/+2
Testing cc1 on pr93032-mztools-unsigned-char.c Benchmark #1: (without patch) Time (mean ± σ): 338.8 ms ± 13.6 ms [User: 323.2 ms, System: 14.2 ms] Range (min … max): 326.7 ms … 363.1 ms 10 runs Benchmark #2: (with patch) Time (mean ± σ): 332.3 ms ± 12.8 ms [User: 316.6 ms, System: 14.3 ms] Range (min … max): 322.5 ms … 357.4 ms 10 runs Summary ./cc1.new ran 1.02 ± 0.06 times faster than ./cc1.old gcc/analyzer/ChangeLog: * store.cc (store::store): Presize m_cluster_map. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-11Daily bump.GCC Administrator1-0/+53
2022-03-10analyzer: fix ICE with -fanalyzer-transitivity [PR104863]David Malcolm1-0/+4
gcc/analyzer/ChangeLog: PR analyzer/104863 * constraint-manager.cc (constraint_manager::add_constraint): Refresh the EC IDs when adding constraints implied by offsets. gcc/testsuite/ChangeLog: PR analyzer/104863 * gcc.dg/analyzer/torture/pr104863.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-10analyzer: add notes to write-to-const/string from access attr [PR104793]David Malcolm8-4/+320
The previous patch extended -Wanalyzer-write-to-const -Wanalyzer-write-to-string-literal to make use of __attribute__ ((access, ....), but the results could be inscrutable. This patch adds notes to such diagnostics to give the user a reason for why the analyzer is complaining. Example output: test.c: In function 'main': test.c:15:13: warning: write to string literal [-Wanalyzer-write-to-string-literal] 15 | if (getrandom((char *)test, sizeof(buf), GRND_RANDOM)) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'main': event 1 | | 15 | if (getrandom((char *)test, sizeof(buf), GRND_RANDOM)) | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (1) write to string literal here | test.c:3:5: note: parameter 1 of 'getrandom' marked with attribute 'access (write_only, 1, 2)' 3 | int getrandom (void *__buffer, size_t __length, | ^~~~~~~~~ Unfortunately we don't have location information for the attributes themselves, just the function declaration, and there doesn't seem to be a good way of getting at the location of the individual parameters from the middle end (the C and C++ FEs both have get_fndecl_argument_location, but the implementations are different). gcc/analyzer/ChangeLog: PR analyzer/104793 * analyzer.h (class pending_note): New forward decl. * diagnostic-manager.cc (saved_diagnostic::saved_diagnostic): Initialize m_notes. (saved_diagnostic::operator==): Compare m_notes. (saved_diagnostic::add_note): New. (saved_diagnostic::emit_any_notes): New. (diagnostic_manager::add_note): New. (diagnostic_manager::emit_saved_diagnostic): Call emit_any_notes after emitting the warning. * diagnostic-manager.h (saved_diagnostic::add_note): New decl. (saved_diagnostic::emit_any_notes): New decl. (saved_diagnostic::m_notes): New field. (diagnostic_manager::add_note): New decl. * engine.cc (impl_region_model_context::add_note): New. * exploded-graph.h (impl_region_model_context::add_note): New decl. * pending-diagnostic.h (class pending_note): New. (class pending_note_subclass): New template. * region-model.cc (class reason_attr_access): New. (check_external_function_for_access_attr): Add class annotating_ctxt and use it when checking region. (noop_region_model_context::add_note): New. * region-model.h (region_model_context::add_note): New vfunc. (noop_region_model_context::add_note): New decl. (class region_model_context_decorator): New. (class note_adding_context): New. gcc/testsuite/ChangeLog: PR analyzer/104793 * gcc.dg/analyzer/write-to-const-2.c: Add dg-message directives for expected notes. * gcc.dg/analyzer/write-to-function-1.c: Likewise. * gcc.dg/analyzer/write-to-string-literal-2.c: Likewise. * gcc.dg/analyzer/write-to-string-literal-3.c: Likewise. * gcc.dg/analyzer/write-to-string-literal-4.c: Likewise. * gcc.dg/analyzer/write-to-string-literal-5.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-10analyzer: check for writes to consts via access attr [PR104793]David Malcolm2-0/+61
This patch extends: -Wanalyzer-write-to-const -Wanalyzer-write-to-string-literal so that they will check for __attribute__ ((access, ....) on calls to externally-defined functions, and complain about read-only regions pointed to by arguments marked with a "write_only" or "read_write" attribute. gcc/analyzer/ChangeLog: PR analyzer/104793 * region-model.cc (region_model::check_external_function_for_access_attr): New. (region_model::handle_unrecognized_call): Call it. * region-model.h (region_model::check_external_function_for_access_attr): New decl. (region_model::handle_unrecognized_call): New decl. gcc/testsuite/ChangeLog: PR analyzer/104793 * gcc.dg/analyzer/write-to-const-2.c: New test. * gcc.dg/analyzer/write-to-function-1.c: New test. * gcc.dg/analyzer/write-to-string-literal-2.c: New test. * gcc.dg/analyzer/write-to-string-literal-3.c: New test. * gcc.dg/analyzer/write-to-string-literal-4.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-10analyzer: fix duplicates in check_for_tainted_size_argDavid Malcolm1-0/+4
gcc/analyzer/ChangeLog: * sm-taint.cc (taint_state_machine::check_for_tainted_size_arg): Avoid generating duplicate saved_diagnostics by only handling the rdwr_map entry for the ptrarg, not the duplicate entry for the sizarg. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/taint-size-access-attr-1.c: Add -fanalyzer-show-duplicate-count to options; verify that a duplicate was not created for the tainted size. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-08Daily bump.GCC Administrator1-0/+14
2022-03-07analyzer: fix leak suppression at end of 'main' [PR101983]David Malcolm1-2/+46
PR analyzer/101983 reports what I thought were false positives from -Wanalyzer-malloc-leak, but on closer inspection, the analyzer is correctly reporting heap-allocated buffers that are no longer reachable. However, these "leaks" occur at the end of "main". The analyzer already has some logic to avoid reporting leaks at the end of main, where the leak is detected at the end of the EXIT basic block. However, in this case, the leak is detected at the clobber in BB 2 here: <bb 2> : func (&res); res ={v} {CLOBBER(eol)}; _4 = 0; <bb 3> : <L0>: return _4; where we have a chain BB 2 -> BB 3 -> EXIT BB. This patch generalizes the "are we at the end of 'main'" detection to handle such cases, silencing -Wanalyzer-malloc-leak on them. There's a remaining issue where the analyzer unhelpfully describes one of the leaking values as '<unknown>', rather than 'res.a', but I'm leaving that for a followup (covered by PR analyzer/99771). gcc/analyzer/ChangeLog: PR analyzer/101983 * engine.cc (returning_from_function_p): New. (impl_region_model_context::on_state_leak): Use it when rejecting leaks at the return from "main". gcc/testsuite/ChangeLog: PR analyzer/101983 * gcc.dg/analyzer/pr101983-main.c: New test. * gcc.dg/analyzer/pr101983-not-main.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-03-07Fix up duplicated duplicated words in commentsJakub Jelinek4-5/+5
Like in r10-7215-g700d4cb08c88aec37c13e21e63dd61fd698baabc 2 years ago, I've run grep -v 'long long\|optab optab\|template template\|double double' *.{[chS],cc} */*.{[chS],cc} *.def config/*/* 2>/dev/null | grep ' \([a-zA-Z]\+\) \1 ' and for the cases that looked clearly wrong changed them, mostly by removing one of the duplicated words but in some cases with other changes. 2022-03-07 Jakub Jelinek <jakub@redhat.com> gcc/ * tree-ssa-propagate.cc: Fix up duplicated word issue in a comment. * config/riscv/riscv.cc: Likewise. * config/darwin.h: Likewise. * config/i386/i386.cc: Likewise. * config/aarch64/thunderx3t110.md: Likewise. * config/aarch64/fractional-cost.h: Likewise. * config/vax/vax.cc: Likewise. * config/rs6000/pcrel-opt.md: Likewise. * config/rs6000/predicates.md: Likewise. * ctfc.h: Likewise. * tree-ssa-uninit.cc: Likewise. * value-relation.h: Likewise. * gimple-range-gori.cc: Likewise. * ipa-polymorphic-call.cc: Likewise. * pointer-query.cc: Likewise. * ipa-sra.cc: Likewise. * internal-fn.cc: Likewise. * varasm.cc: Likewise. * gimple-ssa-warn-access.cc: Likewise. gcc/analyzer/ * store.cc: Fix up duplicated word issue in a comment. * analyzer.cc: Likewise. * engine.cc: Likewise. * sm-taint.cc: Likewise. gcc/c-family/ * c-attribs.cc: Fix up duplicated word issue in a comment. gcc/cp/ * cvt.cc: Fix up duplicated word issue in a comment. * pt.cc: Likewise. * module.cc: Likewise. * coroutines.cc: Likewise. gcc/fortran/ * trans-expr.cc: Fix up duplicated word issue in a comment. * gfortran.h: Likewise. * scanner.cc: Likewise. gcc/jit/ * libgccjit.h: Fix up duplicated word issue in a comment.