aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer
AgeCommit message (Collapse)AuthorFilesLines
2021-05-19Daily bump.GCC Administrator1-0/+8
2021-05-18analyzer: fix missing leak after call to strsep [PR100615]David Malcolm1-0/+28
PR analyzer/100615 reports a missing leak diagnostic. The issue is that the code calls strsep which the analyzer doesn't have special knowledge of, and so conservatively assumes that it could free the pointer, so drops malloc state for it. Properly "teaching" the analyzer about strsep would require it to support bifurcating state at a call, which is currently fiddly to do, so for now this patch notes that strsep doesn't affect the malloc state machine, allowing the analyzer to correctly detect the leak. gcc/analyzer/ChangeLog: PR analyzer/100615 * sm-malloc.cc: Include "analyzer/function-set.h". (malloc_state_machine::on_stmt): Call unaffected_by_call_p and bail on the functions it recognizes. (malloc_state_machine::unaffected_by_call_p): New. gcc/testsuite/ChangeLog: PR analyzer/100615 * gcc.dg/analyzer/pr100615.c: New test.
2021-05-11Daily bump.GCC Administrator1-0/+13
2021-05-10Come up with startswith function.Martin Liska1-3/+2
gcc/ada/ChangeLog: * gcc-interface/utils.c (def_builtin_1): Use startswith function instead of strncmp. gcc/analyzer/ChangeLog: * sm-file.cc (is_file_using_fn_p): Use startswith function instead of strncmp. gcc/ChangeLog: * builtins.c (is_builtin_name): Use startswith function instead of strncmp. * collect2.c (main): Likewise. (has_lto_section): Likewise. (scan_libraries): Likewise. * coverage.c (coverage_checksum_string): Likewise. (coverage_init): Likewise. * dwarf2out.c (is_cxx): Likewise. (gen_compile_unit_die): Likewise. * gcc-ar.c (main): Likewise. * gcc.c (init_spec): Likewise. (read_specs): Likewise. (execute): Likewise. (check_live_switch): Likewise. * genattrtab.c (write_attr_case): Likewise. (IS_ATTR_GROUP): Likewise. * gencfn-macros.c (main): Likewise. * gengtype.c (type_for_name): Likewise. (gen_rtx_next): Likewise. (get_file_langdir): Likewise. (write_local): Likewise. * genmatch.c (get_operator): Likewise. (get_operand_type): Likewise. (expr::gen_transform): Likewise. * genoutput.c (validate_optab_operands): Likewise. * incpath.c (add_sysroot_to_chain): Likewise. * langhooks.c (lang_GNU_C): Likewise. (lang_GNU_CXX): Likewise. (lang_GNU_Fortran): Likewise. (lang_GNU_OBJC): Likewise. * lto-wrapper.c (run_gcc): Likewise. * omp-general.c (omp_max_simt_vf): Likewise. * omp-low.c (omp_runtime_api_call): Likewise. * opts-common.c (parse_options_from_collect_gcc_options): Likewise. * read-rtl-function.c (function_reader::read_rtx_operand_r): Likewise. * real.c (real_from_string): Likewise. * selftest.c (assert_str_startswith): Likewise. * timevar.c (timer::validate_phases): Likewise. * tree.c (get_file_function_name): Likewise. * ubsan.c (ubsan_use_new_style_p): Likewise. * varasm.c (default_function_rodata_section): Likewise. (incorporeal_function_p): Likewise. (default_section_type_flags): Likewise. * system.h (startswith): Define startswith. gcc/c-family/ChangeLog: * c-ada-spec.c (print_destructor): Use startswith function instead of strncmp. (dump_ada_declaration): Likewise. * c-common.c (disable_builtin_function): Likewise. (def_builtin_1): Likewise. * c-format.c (check_tokens): Likewise. (check_plain): Likewise. (convert_format_name_to_system_name): Likewise. gcc/c/ChangeLog: * c-aux-info.c (affix_data_type): Use startswith function instead of strncmp. * c-typeck.c (build_function_call_vec): Likewise. * gimple-parser.c (c_parser_gimple_parse_bb_spec): Likewise. gcc/cp/ChangeLog: * decl.c (duplicate_decls): Use startswith function instead of strncmp. (cxx_builtin_function): Likewise. (omp_declare_variant_finalize_one): Likewise. (grokfndecl): Likewise. * error.c (dump_decl_name): Likewise. * mangle.c (find_decomp_unqualified_name): Likewise. (write_guarded_var_name): Likewise. (decl_tls_wrapper_p): Likewise. * parser.c (cp_parser_simple_type_specifier): Likewise. (cp_parser_tx_qualifier_opt): Likewise. * pt.c (template_parm_object_p): Likewise. (dguide_name_p): Likewise. gcc/d/ChangeLog: * d-builtins.cc (do_build_builtin_fn): Use startswith function instead of strncmp. * dmd/dinterpret.c (evaluateIfBuiltin): Likewise. * dmd/dmangle.c: Likewise. * dmd/hdrgen.c: Likewise. * dmd/identifier.c (Identifier::toHChars2): Likewise. gcc/fortran/ChangeLog: * decl.c (variable_decl): Use startswith function instead of strncmp. (gfc_match_end): Likewise. * gfortran.h (gfc_str_startswith): Likewise. * module.c (load_omp_udrs): Likewise. (read_module): Likewise. * options.c (gfc_handle_runtime_check_option): Likewise. * primary.c (match_arg_list_function): Likewise. * trans-decl.c (gfc_get_symbol_decl): Likewise. * trans-expr.c (gfc_conv_procedure_call): Likewise. * trans-intrinsic.c (gfc_conv_ieee_arithmetic_function): Likewise. gcc/go/ChangeLog: * gofrontend/runtime.cc (Runtime::name_to_code): Use startswith function instead of strncmp. gcc/objc/ChangeLog: * objc-act.c (objc_string_ref_type_p): Use startswith function instead of strncmp. * objc-encoding.c (encode_type): Likewise. * objc-next-runtime-abi-02.c (has_load_impl): Likewise.
2021-05-10Remove __cplusplus >= 201103Martin Liska3-11/+0
Right now, we require a C++11 compiler, so the check is not needed any longer. gcc/analyzer/ChangeLog: * program-state.cc (program_state::operator=): Remove __cplusplus >= 201103. (program_state::program_state): Likewise. * program-state.h: Likewise. * region-model.h (class region_model): Remove dead code. gcc/ChangeLog: * bitmap.h (class auto_bitmap): Remove __cplusplus >= 201103. * config/aarch64/aarch64.c: Likewise. * gimple-ssa-store-merging.c (store_immediate_info::store_immediate_info): Likewise. * sbitmap.h: Likewise.
2021-04-25Daily bump.GCC Administrator1-0/+6
2021-04-24analyzer: fix ICE on NULL change.m_expr [PR100244]David Malcolm1-1/+1
PR analyzer/100244 reports an ICE on a -Wanalyzer-free-of-non-heap due to a case where free_of_non_heap::describe_state_change can be passed a NULL change.m_expr for a suitably complicated symbolic value. Bulletproof it by checking for change.m_expr being NULL before dereferencing it. gcc/analyzer/ChangeLog: PR analyzer/100244 * sm-malloc.cc (free_of_non_heap::describe_state_change): Bulletproof against change.m_expr being NULL. gcc/testsuite/ChangeLog: PR analyzer/100244 * g++.dg/analyzer/pr100244.C: New test.
2021-04-14Daily bump.GCC Administrator1-0/+12
2021-04-12gimple UIDs, LTO and -fanalyzer [PR98599]David Malcolm2-4/+68
gimple.h has this comment for gimple's uid field: /* UID of this statement. This is used by passes that want to assign IDs to statements. It must be assigned and used by each pass. By default it should be assumed to contain garbage. */ unsigned uid; and gimple_set_uid has: Please note that this UID property is supposed to be undefined at pass boundaries. This means that a given pass should not assume it contains any useful value when the pass starts and thus can set it to any value it sees fit. which suggests that any pass can use the uid field as an arbitrary scratch space. PR analyzer/98599 reports a case where this error occurs in LTO mode: fatal error: Cgraph edge statement index out of range on certain inputs with -fanalyzer. The error occurs in the LTRANS phase after -fanalyzer runs in the WPA phase. The analyzer pass writes to the uid fields of all stmts. The error occurs when LTRANS is streaming callgraph edges back in. The LTO format uses stmt uids to associate call stmts with callgraph edges between WPA and LTRANS. For example, in lto-cgraph.c, lto_output_edge writes out the gimple_uid, and input_edge reads it back in. lto_prepare_function_for_streaming has code to renumber the stmt UIDs when the code is streamed back out, but for some reason this isn't called for clones: 307 /* Do body modifications needed for streaming before we fork out 308 worker processes. */ 309 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 310 if (!node->clone_of && gimple_has_body_p (node->decl)) 311 lto_prepare_function_for_streaming (node); Hence the combination of -fanalyzer and -flto will fail in LTRANS's stream-in if any function clones are encountered. It's not fully clear to me why this isn't done for clones, and what the correct fix should be to allow arbitrary changes to uids within WPA passes. In the meantime, this patch works around the issue by updating the analyzer to save and restore the UIDs, fixing the error. gcc/analyzer/ChangeLog: PR analyzer/98599 * supergraph.cc (saved_uids::make_uid_unique): New. (saved_uids::restore_uids): New. (supergraph::supergraph): Replace assignments to stmt->uid with calls to m_stmt_uids.make_uid_unique. (supergraph::~supergraph): New. * supergraph.h (class saved_uids): New. (supergraph::~supergraph): New decl. (supergraph::m_stmt_uids): New field. gcc/testsuite/ChangeLog: PR analyzer/98599 * gcc.dg/analyzer/pr98599-a.c: New test. * gcc.dg/analyzer/pr98599-b.c: New test.
2021-04-11Daily bump.GCC Administrator1-0/+6
2021-04-10analyzer: fix ICE on assignment from STRING_CST when building path [PR100011]David Malcolm1-1/+1
gcc/analyzer/ChangeLog: PR analyzer/100011 * region-model.cc (region_model::on_assignment): Avoid NULL dereference if ctxt is NULL when assigning from a STRING_CST. gcc/testsuite/ChangeLog: PR analyzer/100011 * gcc.dg/analyzer/pr100011.c: New test.
2021-04-09Daily bump.GCC Administrator1-0/+94
2021-04-08analyzer: fix leak false +ves due to maybe-clobbered regions [PR99042,PR99774]David Malcolm10-73/+309
Prior to this patch, program_state::detect_leaks worked by finding all live svalues in the old state and in the new state, and calling on_svalue_leak for each svalue that has changed from being live to not being live. PR analyzer/99042 and PR analyzer/99774 both describe false leak diagnostics from -fanalyzer (a false FILE * leak in git, and a false malloc leak in qemu, respectively). In both cases the root cause of the false leak diagnostic relates to svalues no longer being explicitly bound in the store due to regions being conservatively clobbered, due to an unknown function being called, or due to a write through a pointer that could alias the region, respectively. We have a transition from an svalue being explicitly live to not being explicitly live - but only because the store is being conservative, clobbering the binding. The leak detection is looking for transitions from "definitely live" to "not definitely live", when it should be looking for transitions from "definitely live" to "definitely not live". This patch introduces a new class to temporarily capture information about svalues that were explicitly live, but for which a region bound to them got clobbered for conservative reasons. This new "uncertainty_t" class is passed around to capture the data long enough for use in program_state::detect_leaks, where it is used to only complain about svalues that were definitely live and are now both not definitely live *or* possibly-live i.e. definitely not-live. The class also captures for which svalues we can't meaningfully track sm-state anymore, and resets the svalues back to the "start" state. Together, these changes fix the false leak reports. gcc/analyzer/ChangeLog: PR analyzer/99042 PR analyzer/99774 * engine.cc (impl_region_model_context::impl_region_model_context): Add uncertainty param and use it to initialize m_uncertainty. (impl_region_model_context::get_uncertainty): New. (impl_sm_context::get_fndecl_for_call): Add NULL for new uncertainty param when constructing impl_region_model_context. (impl_sm_context::get_state): Likewise. (impl_sm_context::set_next_state): Likewise. (impl_sm_context::warn): Likewise. (exploded_node::on_stmt): Add uncertainty param and use it when constructing impl_region_model_context. (exploded_node::on_edge): Add uncertainty param and pass to on_edge call. (exploded_node::detect_leaks): Create uncertainty_t and pass to impl_region_model_context. (exploded_graph::get_or_create_node): Create uncertainty_t and pass to prune_for_point. (maybe_process_run_of_before_supernode_enodes): Create uncertainty_t and pass to impl_region_model_context. (exploded_graph::process_node): Create uncertainty_t instances and pass around as needed. * exploded-graph.h (impl_region_model_context::impl_region_model_context): Add uncertainty param. (impl_region_model_context::get_uncertainty): New decl. (impl_region_model_context::m_uncertainty): New field. (exploded_node::on_stmt): Add uncertainty param. (exploded_node::on_edge): Likewise. * program-state.cc (sm_state_map::on_liveness_change): Get uncertainty from context and use it to unset sm-state from svalues as appropriate. (program_state::on_edge): Add uncertainty param and use it when constructing impl_region_model_context. Fix indentation. (program_state::prune_for_point): Add uncertainty param and use it when constructing impl_region_model_context. (program_state::detect_leaks): Get any uncertainty from ctxt and use it to get maybe-live svalues for dest_state, rather than definitely-live ones; use this when determining which svalues have leaked. (selftest::test_program_state_merging): Create uncertainty_t and pass to impl_region_model_context. * program-state.h (program_state::on_edge): Add uncertainty param. (program_state::prune_for_point): Likewise. * region-model-impl-calls.cc (call_details::get_uncertainty): New. (region_model::impl_call_memcpy): Pass uncertainty to mark_region_as_unknown call. (region_model::impl_call_memset): Likewise. (region_model::impl_call_strcpy): Likewise. * region-model-reachability.cc (reachable_regions::handle_sval): Also add sval to m_mutable_svals. * region-model.cc (region_model::on_assignment): Pass any uncertainty from ctxt to the store::set_value call. (region_model::handle_unrecognized_call): Get any uncertainty from ctxt and use it to record mutable svalues at the unknown call. (region_model::get_reachable_svalues): Add uncertainty param and use it to mark any maybe-bound svalues as being reachable. (region_model::set_value): Pass any uncertainty from ctxt to the store::set_value call. (region_model::mark_region_as_unknown): Add uncertainty param and pass it on to the store::mark_region_as_unknown call. (region_model::update_for_call_summary): Add uncertainty param and pass it on to the region_model::mark_region_as_unknown call. * region-model.h (call_details::get_uncertainty): New decl. (region_model::get_reachable_svalues): Add uncertainty param. (region_model::mark_region_as_unknown): Add uncertainty param. (region_model_context::get_uncertainty): New vfunc. (noop_region_model_context::get_uncertainty): New vfunc implementation. * store.cc (dump_svalue_set): New. (uncertainty_t::dump_to_pp): New. (uncertainty_t::dump): New. (binding_cluster::clobber_region): Pass NULL for uncertainty to remove_overlapping_bindings. (binding_cluster::mark_region_as_unknown): Add uncertainty param and pass it to remove_overlapping_bindings. (binding_cluster::remove_overlapping_bindings): Add uncertainty param. Use it to record any svalues that were in clobbered bindings. (store::set_value): Add uncertainty param. Pass it to binding_cluster::mark_region_as_unknown when handling symbolic regions. (store::mark_region_as_unknown): Add uncertainty param and pass it to binding_cluster::mark_region_as_unknown. (store::remove_overlapping_bindings): Add uncertainty param and pass it to binding_cluster::remove_overlapping_bindings. * store.h (binding_cluster::mark_region_as_unknown): Add uncertainty param. (binding_cluster::remove_overlapping_bindings): Likewise. (store::set_value): Likewise. (store::mark_region_as_unknown): Likewise. gcc/testsuite/ChangeLog: PR analyzer/99042 PR analyzer/99774 * gcc.dg/analyzer/pr99042.c: New test. * gcc.dg/analyzer/pr99774-1.c: New test. * gcc.dg/analyzer/pr99774-2.c: New test.
2021-04-06Daily bump.GCC Administrator1-0/+18
2021-04-05analyzer: fix ICE on zero-arg calls passed to __attribute__((nonnull)) [PR ↵David Malcolm2-2/+3
99906] gcc/analyzer/ChangeLog: PR analyzer/99906 * analyzer.cc (maybe_reconstruct_from_def_stmt): Fix NULL dereference on calls with zero arguments. * sm-malloc.cc (malloc_state_machine::on_stmt): When handling __attribute__((nonnull)), only call get_diagnostic_tree if the result will be used. gcc/testsuite/ChangeLog: PR analyzer/99906 * gcc.dg/analyzer/pr99906.c: New test.
2021-04-05analyzer: fix apparent hang with -fanalyzer-verbosity=0 [PR analyzer/99886]David Malcolm1-3/+5
The analyzer appeared to enter an infinite loop on malloc-1.c when -fanalyzer-verbosity=0 was used. In fact, it was slowly counting from 0 to 0xffffffff. Root cause is looping up to effectively ((unsigned)0) - 1 in diagnostic_manager::consolidate_conditions when there are no events in the path. Fixed by the following, which uses signed integers when subtracting from path->num_events () when simplifying checker_paths. gcc/analyzer/ChangeLog: PR analyzer/99886 * diagnostic-manager.cc (diagnostic_manager::prune_interproc_events): Use signed integers when subtracting one from path->num_events (). (diagnostic_manager::consolidate_conditions): Likewise. Convert next_idx to a signed int. gcc/testsuite/ChangeLog: PR analyzer/99886 * gcc.dg/analyzer/pr99886.c: New test.
2021-04-02Daily bump.GCC Administrator1-0/+56
2021-04-01analyzer: record per-enode saved_diagnosticsDavid Malcolm7-55/+65
Various places iterate through all of the saved_diagnostics to find just the ones that are at a given enode. This patch adds a per-enode record of the diagnostics that are at each node, to save iterating through all of the diagnostics each time. gcc/analyzer/ChangeLog: * diagnostic-manager.cc (diagnostic_manager::add_diagnostic): Make enode param non-constant, and call add_diagnostic on it. Add enode index to log message. (diagnostic_manager::add_diagnostic): Make enode param non-constant. * diagnostic-manager.h (diagnostic_manager::add_diagnostic): Likewise for both decls. * engine.cc (impl_region_model_context::impl_region_model_context): Likewise for enode_for_diag. (impl_sm_context::impl_sm_context): Likewise. (impl_sm_context::m_enode_for_diag): Likewise. (exploded_node::dump_dot): Don't pass the diagnostic manager to dump_saved_diagnostics. (exploded_node::dump_saved_diagnostics): Drop param. Iterate directly through all saved diagnostics for the enode, rather than all saved diagnostics in the diagnostic_manager and filtering. (exploded_node::on_stmt): Make non-const. (exploded_node::on_edge): Likewise. (exploded_node::on_longjmp): Likewise. (exploded_node::detect_leaks): Likewise. (exploded_graph::get_or_create_node): Make enode_for_diag param non-const. (exploded_graph_annotator::print_enode): Iterate directly through all saved diagnostics for the enode, rather than all saved diagnostics in the diagnostic_manager and filtering. * exploded-graph.h (impl_region_model_context::impl_region_model_context): Make enode_for_diag param non-constant. (impl_region_model_context::m_enode_for_diag): Likewise. (exploded_node::dump_saved_diagnostics): Drop param. (exploded_node::on_stmt): Make non-const. (exploded_node::on_edge): Likewise. (exploded_node::on_longjmp): Likewise. (exploded_node::detect_leaks): Likewise. (exploded_node::add_diagnostic): New. (exploded_node::get_num_diagnostics): New. (exploded_node::get_saved_diagnostic): New. (exploded_node::m_saved_diagnostics): New. (exploded_graph::get_or_create_node): Make enode_for_diag param non-constant. * feasible-graph.cc (feasible_node::dump_dot): Drop diagnostic_manager from call to dump_saved_diagnostics. * program-state.cc (program_state::on_edge): Convert enode param to non-const pointer. (program_state::prune_for_point): Likewise for enode_for_diag param. * program-state.h (program_state::on_edge): Convert enode param to non-const pointer. (program_state::prune_for_point): Likewise for enode_for_diag param.
2021-04-01Daily bump.GCC Administrator1-0/+16
2021-03-31analyzer: avoid printing '<unknown>' for SSA names [PR99771]David Malcolm5-8/+140
We don't want to print '<unknown>' in our diagnostics, but PR analyzer/99771 lists various cases where -fanalyzer does, due to using the SSA_NAME for a temporary when determining the best tree to use. This can happen in two ways: (a) ...when a better expression than the SSA_NAME could be built, but finding it requires traversing the relationships in the region_model in a graph-like way, rather than by considering individual svalues and regions. (b) ...when the only remaining user of the underlying svalue is the SSA_NAME, typically due to the diagnostic referring to a temporary. I've been experimenting with fixing (a), but don't have a good fix yet. In the meantime, this patch addresses (b) by detecting if we have the SSA_NAME for a temporary, and, for the cases where it's possible, reconstructing a tree by walking the def-stmts. This fixes various cases of (b) and ameliorates some cases of (a). gcc/analyzer/ChangeLog: PR analyzer/99771 * analyzer.cc (maybe_reconstruct_from_def_stmt): New. (fixup_tree_for_diagnostic_1): New. (fixup_tree_for_diagnostic): New. * analyzer.h (fixup_tree_for_diagnostic): New decl. * checker-path.cc (call_event::get_desc): Call fixup_tree_for_diagnostic and use it for the call_with_state call. (warning_event::get_desc): Likewise for the final_event and make_label_text calls. * engine.cc (impl_region_model_context::on_state_leak): Likewise for the on_leak and add_diagnostic calls. * region-model.cc (region_model::get_representative_tree): Likewise for the result. gcc/testsuite/ChangeLog: PR analyzer/99771 * gcc.dg/analyzer/data-model-10.c: Update expected output. * gcc.dg/analyzer/malloc-ipa-13.c: Likewise. * gcc.dg/analyzer/malloc-ipa-13a.c: New test. * gcc.dg/analyzer/pr99771-1.c: New test.
2021-03-31Daily bump.GCC Administrator1-0/+16
2021-03-30analyzer: remove old decl of region::dump_to_ppDavid Malcolm1-5/+0
This was made redundant in the GCC 11 rewrite of state (808f4dfeb3a95f50f15e71148e5c1067f90a126d). gcc/analyzer/ChangeLog: * region.h (region::dump_to_pp): Remove old decl.
2021-03-30analyzer: only call get_diagnostic_tree when it's neededDavid Malcolm4-8/+16
impl_sm_context::get_diagnostic_tree could be expensive, and I find myself needing to put a breakpoint on it to debug PR analyzer/99771, so only call it if we're about to use the result. gcc/analyzer/ChangeLog: * sm-file.cc (fileptr_state_machine::on_stmt): Only call get_diagnostic_tree if the result will be used. * sm-malloc.cc (malloc_state_machine::on_stmt): Likewise. (malloc_state_machine::on_deallocator_call): Likewise. (malloc_state_machine::on_realloc_call): Likewise. (malloc_state_machine::on_realloc_call): Likewise. * sm-sensitive.cc (sensitive_state_machine::warn_for_any_exposure): Likewise. * sm-taint.cc (taint_state_machine::on_stmt): Likewise.
2021-03-26Daily bump.GCC Administrator1-0/+15
2021-03-24analyzer; reset sm-state for SSA names at def-stmts [PR93695,PR99044,PR99716]David Malcolm6-0/+126
Various false positives from -fanalyzer involve SSA names in loops, where sm-state associated with an SSA name from one iteration is erroneously reused in a subsequent iteration. For example, PR analyzer/99716 describes a false "double 'fclose' of FILE 'fp'" on: for (i = 0; i < 2; ++i) { FILE *fp = fopen ("/tmp/test", "w"); fprintf (fp, "hello"); fclose (fp); } where the gimple of the loop body is: fp_7 = fopen ("/tmp/test", "w"); __builtin_fwrite ("hello", 1, 5, fp_7); fclose (fp_7); i_10 = i_1 + 1; where fp_7 transitions to "closed" at the fclose, but is not reset at the subsequent fopen, leading to the false positive when the fclose is re-reached. The fix is to reset sm-state for svalues that involve an SSA name at the SSA name's def-stmt, since the def-stmt effectively changes the meaning of those related svalues. gcc/analyzer/ChangeLog: PR analyzer/93695 PR analyzer/99044 PR analyzer/99716 * engine.cc (exploded_node::on_stmt): Clear sm-state involving an SSA name at the def-stmt of that SSA name. * program-state.cc (sm_state_map::purge_state_involving): New. * program-state.h (sm_state_map::purge_state_involving): New decl. * region-model.cc (selftest::test_involves_p): New. (selftest::analyzer_region_model_cc_tests): Call it. * svalue.cc (class involvement_visitor): New class (svalue::involves_p): New. * svalue.h (svalue::involves_p): New decl. gcc/testsuite/ChangeLog: PR analyzer/93695 PR analyzer/99044 PR analyzer/99716 * gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c: Remove xfail. * gcc.dg/analyzer/pr93695-1.c: New test. * gcc.dg/analyzer/pr99044-1.c: New test. * gcc.dg/analyzer/pr99044-2.c: New test. * gcc.dg/analyzer/pr99716-1.c: New test. * gcc.dg/analyzer/pr99716-2.c: New test. * gcc.dg/analyzer/pr99716-3.c: New test.
2021-03-20Daily bump.GCC Administrator1-0/+6
2021-03-19analyzer: mark epath_finder with DISABLE_COPY_AND_ASSIGN [PR99614]David Malcolm1-0/+2
cppcheck warns that class epath_finder does dynamic memory allocation, but is missing a copy constructor and operator=. This class isn't meant to be copied or assigned, so mark it with DISABLE_COPY_AND_ASSIGN. gcc/analyzer/ChangeLog: PR analyzer/99614 * diagnostic-manager.cc (class epath_finder): Add DISABLE_COPY_AND_ASSIGN.
2021-03-16Daily bump.GCC Administrator1-0/+4
2021-03-15analyzer: fix missing comma in initializerMartin Liska1-1/+1
Fixes the following valid warning: gcc/analyzer/sm-file.cc:250:5: warning: suspicious concatenation of string literals in an array initialization; did you mean to separate the elements with a comma? [-Wstring-concatenation] gcc/analyzer/ChangeLog: * sm-file.cc (get_file_using_fns): Add missing comma in initializer.
2021-03-12Daily bump.GCC Administrator1-0/+56
2021-03-11analyzer: new implementation of shortest feasible path [PR96374]David Malcolm9-77/+1276
The analyzer builds an exploded graph of (point,state) pairs and when it finds a problem, records a diagnostic at the relevant exploded node. Once it has finished exploring the graph, the analyzer needs to generate the shortest feasible path through the graph to each diagnostic's node. This is used: - for rejecting diagnostics that are infeasible (due to impossible sets of constraints), - for use in determining which diagnostic to use in each deduplication set (the one with the shortest path), and - for building checker_paths for the "winning" diagnostics, giving a list of events Prior to this patch the analyzer simply found the shortest path to the node, and then checked it for feasibility, which could lead to falsely rejecting diagnostics: "the shortest path, if feasible" is not the same as "the shortest feasible path" (PR analyzer/96374). An example is PR analyzer/93355, where this issue causes the analyzer to fail to emit a leak warning for a missing fclose on an error-handling path in intl/localealias.c. This patch implements a new algorithm for finding the shortest feasible path to an exploded node: instead of simply finding the shortest path, the new algorithm uses a worklist to iteratively build a tree of path prefixes, which are feasible paths by construction, until a path to the target node is found. The worklist is prioritized, so that the first feasible path discovered is the shortest possible feasible path. The algorithm continues trying paths until the target node is reached or a limit is exceeded, in which case the diagnostic is treated as being infeasible (which could still be a false negative, but is much less likely to happen than before). Iteratively building a tree of paths allows for work to be reused, and the tree can be dumped in .dot form (via a new -fdump-analyzer-feasibility option), making it much easier to debug compared to other approaches I tried. Doing so fixes the missing leak warning for PR analyzer/93355 and various other test cases. Testing: - I manually verified that the behavior is determistic using 50 builds of pr93355-localealias.c. All dumps were identical. - I manually verified that it still builds with --disable-analyzer. - Lightly tested with valgrind; no additional issues. - Lightly performance tested, showing a slight speed regression to the analyzer relative to before the patch, but correctness for this issue is more important than the slight performance hit for the analyzer. gcc/ChangeLog: PR analyzer/96374 * Makefile.in (ANALYZER_OBJS): Add analyzer/feasible-graph.o and analyzer/trimmed-graph.o. * doc/analyzer.texi (Analyzer Paths): Rewrite description of feasibility checking to reflect new implementation. * doc/invoke.texi (-fdump-analyzer-feasibility): Document new option. * shortest-paths.h (shortest_paths::get_shortest_distance): New. gcc/analyzer/ChangeLog: PR analyzer/96374 * analyzer.opt (-param=analyzer-max-infeasible-edges=): New param. (fdump-analyzer-feasibility): New flag. * diagnostic-manager.cc: Include "analyzer/trimmed-graph.h" and "analyzer/feasible-graph.h". (epath_finder::epath_finder): Convert m_sep to a pointer and only create it if !flag_analyzer_feasibility. (epath_finder::~epath_finder): New. (epath_finder::m_sep): Convert to a pointer. (epath_finder::get_best_epath): Add param "diag_idx" and use it when logging. Rather than finding the shortest path and then checking feasibility, instead use explore_feasible_paths unless !flag_analyzer_feasibility, in which case simply use the shortest path, and note if it is infeasible. Update for m_sep becoming a pointer. (class feasible_worklist): New. (epath_finder::explore_feasible_paths): New. (epath_finder::process_worklist_item): New. (class dump_eg_with_shortest_path): New. (epath_finder::dump_trimmed_graph): New. (epath_finder::dump_feasible_graph): New. (saved_diagnostic::saved_diagnostic): Add "idx" param, using it on new field m_idx. (saved_diagnostic::to_json): Dump m_idx. (saved_diagnostic::calc_best_epath): Pass m_idx to get_best_epath. Remove assertion that m_problem was set when m_best_epath is NULL. (diagnostic_manager::add_diagnostic): Pass an index when created saved_diagnostic instances. * diagnostic-manager.h (saved_diagnostic::saved_diagnostic): Add "idx" param. (saved_diagnostic::get_index): New accessor. (saved_diagnostic::m_idx): New field. * engine.cc (exploded_node::dump_dot): Call args.dump_extra_info. Move code to... (exploded_node::dump_processed_stmts): ...this new function and... (exploded_node::dump_saved_diagnostics): ...this new function. Add index of each diagnostic. (exploded_edge::dump_dot): Move bulk of code to... (exploded_edge::dump_dot_label): ...this new function. * exploded-graph.h (eg_traits::dump_args_t::dump_extra_info): New vfunc. (exploded_node::dump_processed_stmts): New decl. (exploded_node::dump_saved_diagnostics): New decl. (exploded_edge::dump_dot_label): New decl. * feasible-graph.cc: New file. * feasible-graph.h: New file. * trimmed-graph.cc: New file. * trimmed-graph.h: New file. gcc/testsuite/ChangeLog: PR analyzer/96374 * gcc.dg/analyzer/dot-output.c: Add -fdump-analyzer-feasibility to options. * gcc.dg/analyzer/feasibility-1.c (test_6): Remove xfail. (test_7): New. * gcc.dg/analyzer/pr93355-localealias-feasibility-2.c: Remove xfail. * gcc.dg/analyzer/pr93355-localealias-feasibility-3.c: Remove xfails. * gcc.dg/analyzer/pr93355-localealias-feasibility.c: Remove -fno-analyzer-feasibility from options. * gcc.dg/analyzer/pr93355-localealias.c: Likewise. * gcc.dg/analyzer/unknown-fns-4.c: Remove xfail.
2021-03-11analyzer: support reverse direction in shortest-paths.hDavid Malcolm1-1/+1
This patch generalizes shortest-path.h so that it can be used to find the shortest path from each node to a given target node (on top of the existing support for finding the shortest path from a given origin node to each node). I've marked this as "analyzer" as this is the only code using shortest-paths.h. This patch is required by followup work to fix PR analyzer/96374. gcc/analyzer/ChangeLog: * diagnostic-manager.cc (epath_finder::epath_finder): Update shortest_paths init for new param. gcc/ChangeLog: * digraph.cc (selftest::test_shortest_paths): Update shortest_paths init for new param. Add test of SPS_TO_GIVEN_TARGET. * shortest-paths.h (enum shortest_path_sense): New. (shortest_paths::shortest_paths): Add "sense" param. Update for renamings. Generalize to use "sense" param. (shortest_paths::get_shortest_path): Rename param. (shortest_paths::m_sense): New field. (shortest_paths::m_prev): Rename... (shortest_paths::m_best_edge): ...to this. (shortest_paths::get_shortest_path): Update for renamings. Conditionalize flipping of path on sense of traversal.
2021-03-11Daily bump.GCC Administrator1-0/+19
2021-03-10analyzer: factor out new class feasibility_stateDavid Malcolm2-101/+172
As preparatory work for a fix to PR analyzer/96374, this patch moves the core state-update logic from the loop in exploded_path::feasible_p into a new class feasibility_state. No functional change intended. gcc/analyzer/ChangeLog: PR analyzer/96374 * engine.cc (exploded_path::feasible_p): Move "snodes_visited" and "model" locals into a new class feasibility_state. Move heart of per-edge processing into feasibility_state::maybe_update_for_edge. (feasibility_state::feasibility_state): New. (feasibility_state::maybe_update_for_edge): New, based on loop body in exploded_path::feasible_p. * exploded-graph.h (class feasibility_state): New.
2021-03-10committed: analyzer: remove duplicated vfuncsDavid Malcolm1-18/+10
Implement dyn_cast_callgraph_superedge once in callgraph_superedge, rather than twice in the two subclasses. Spotted whilst working on a patch for call summaries. gcc/analyzer/ChangeLog: * supergraph.h (callgraph_superedge::dyn_cast_callgraph_superedge): New. (call_superedge::dyn_cast_callgraph_superedge): Delete. (return_superedge::dyn_cast_callgraph_superedge): Delete.
2021-03-03Daily bump.GCC Administrator1-0/+5
2021-03-02analyzer: remove dead codeMartin Liska1-5/+1
The issue is reported by Clang: warning: private field 'm_engine' is not used [-Wunused-private-field] gcc/analyzer/ChangeLog: * diagnostic-manager.cc (diagnostic_manager::emit_saved_diagnostics): Do not pass engine.
2021-02-27Daily bump.GCC Administrator1-0/+65
2021-02-26analyzer: implement exploded_path copy ctorDavid Malcolm2-1/+9
gcc/analyzer/ChangeLog: * engine.cc (exploded_path::exploded_path): New copy-ctor. * exploded-graph.h (exploded_path::operator=): Drop decl.
2021-02-25analyzer: eliminate dedupe_candidate [PR96374]David Malcolm4-206/+244
In gcc/analyzer/diagnostic-manager.cc the code partitions saved_diagnostic instances by dedupe_key, and tries to find the "best" saved_diagnostic for each dedupe_key. Ideally we would find the shortest feasible path for each saved_diagnostic and pick the winner in each deduplication set. Currently we merely approximate that by finding the shortest path for each saved_diagnostic, and checking to see if it feasible, rejecting the saved_diagnostic if it is not. The "shortest path, or nothing if it's infeasible" is not the same as the "shortest feasible path", and this leads to false negatives, where we reject valid diagnostics, tracked as PR analyzer/96374. I have been attempting various fixes for this, but in doing so I found that the existing structure of the code makes things unnecessarily awkward: each dedupe_set had a a dedupe_candidate which stored the best epath for that set, creating it from the shortest path when that dedupe_candidate was constructed. This patch eliminates the dedupe_candidate, instead storing the best epath for each saved_diagnostic within the saved_diagnostic itself, along with any feasibility_problem, and eliminating a redundant "status" field. The logic for finding the best epath is moved to a new epath_finder::get_best_epath subroutine, introducing an epath_finder class to give a place to cache state. This patch merely copies over the existing logic to epath_finder::get_best_epath, so no functional change is intended, but the patch simplifies the logic and makes it much easier to experiment with alternate implementations as I try to fix PR analyzer/96374. I attempted another version of this patch in which I added a dedupe_set class and partitioned saved_diagnostics into them as the diagnostics were added, but in this earlier iteration of the patch there were regressions e.g. from gcc.dg/analyzer/zlib-4.c where 4 deduplication sets became 3. The issue was that the deduplication logic needs source locations, which need gimple statements, and the stmt_finder needs epaths to run. Finding the epaths needs the full egraph (as opposed to the egraph in its state at the time when the diagnostic is saved). Hence the partitioning needs to happen after the egraph is fully explored. I backed up the earlier patch kit to: https://dmalcolm.fedorapeople.org/gcc/2021-02-23/feasibility-v0.3-relative-to-72d78655a91bb2f89ac4432cfd6374380d6f9987/ gcc/analyzer/ChangeLog: PR analyzer/96374 * diagnostic-manager.cc (class epath_finder): New. (epath_finder::get_best_epath): New. (saved_diagnostic::saved_diagnostic): Update for replacement of m_state and m_epath_length with m_best_epath. (saved_diagnostic::~saved_diagnostic): Delete m_best_epath. (saved_diagnostic::to_json): Update "path_length" to be optional. (saved_diagnostic::calc_best_epath): New, based on dedupe_winners::add and parts of dedupe_key::dedupe_key. (saved_diagnostic::get_epath_length): New. (saved_diagnostic::add_duplicate): New. (dedupe_key::dedupe_key): Drop epath param. Move invocation of stmt_finder to saved_diagnostic::calc_best_epath. (class dedupe_candidate): Delete. (class dedupe_hash_map_traits): Update to use saved_diagnotic * rather than dedupe_candidate * as the value_type/compare_type. (dedupe_winners::~dedupe_winners): Don't delete the values. (dedupe_winners::add): Convert param from shortest_exploded_paths to epath_finder. Drop "eg" param. Drop dedupe_candidate, moving path generation and feasiblity checking to epath_finder::get_best_epath. Update winner-selection for move of epaths from dedupe_candidate to saved_diagnostic. (dedupe_winners::emit_best): Update for removal of class dedupe_candidate. (dedupe_winners::map_t): Update to use saved_diagnotic * rather than dedupe_candidate * as the value_type/compare_type. (diagnostic_manager::emit_saved_diagnostics): Move shortest_exploded_paths instance into epath_finder and pass that around instead. (diagnostic_manager::emit_saved_diagnostic): Drop epath, stmt and num_dupes params, instead getting these from the saved_diagnostic. Use correct location in inform_n call. * diagnostic-manager.h (class epath_finder): New forward decl. (saved_diagnostic::status): Drop enum. (saved_diagnostic::set_feasible): Drop. (saved_diagnostic::set_infeasible): Drop. (saved_diagnostic::get_status): Drop. (saved_diagnostic::calc_best_epath): New decl. (saved_diagnostic::get_best_epath): New decl. (saved_diagnostic::get_epath_length): New decl. (saved_diagnostic::set_epath_length): Drop. (saved_diagnostic::get_epath_length): Drop inline implementation. (saved_diagnostic::add_duplicate): New. (saved_diagnostic::get_num_dupes): New. (saved_diagnostic::m_d): Document ownership. (saved_diagnostic::m_trailing_eedge): Make const. (saved_diagnostic::m_status): Drop field. (saved_diagnostic::m_epath_length): Drop field. (saved_diagnostic::m_best_epath): New field. (saved_diagnostic::m_problem): Document ownership. (saved_diagnostic::m_duplicates): New field. (diagnostic_manager::emit_saved_diagnostic): Drop params epath, stmt, and num_dupes. * engine.cc (exploded_graph_annotator::print_saved_diagnostic): Update for changes to saved_diagnostic class. * exploded-graph.h (exploded_path::feasible_p): Drop unused overloaded decl.
2021-02-26Daily bump.GCC Administrator1-0/+16
2021-02-24analyzer: fix false positive on realloc [PR99193]David Malcolm4-2/+88
PR analyzer/99193 describes various false positives from -Wanalyzer-mismatching-deallocation on realloc(3) calls of the form: | 31 | void *p = malloc (1024); | | ^~~~~~~~~~~~~ | | | | | (1) allocated here (expects deallocation with ‘free’) | 32 | void *q = realloc (p, 4096); | | ~~~~~~~~~~~~~~~~~ | | | | | (2) deallocated with ‘realloc’ here; allocation at (1) expects deallocation with ‘free’ | The underlying issue is that the analyzer has no knowledge of realloc(3), and realloc has awkward semantics. Unfortunately, the analyzer is currently structured so that each call statement can only have at most one successor state; there is no way to "bifurcate" the state, or have N-way splits into multiple outcomes. The existing "on_stmt" code works on a copy of the next state, updating it in place, rather than copying it and making any necessary changes. I did this as an optimization to avoid unnecessary copying of state objects, but it makes it hard to support multiple outcomes. (ideally our state objects would be immutable and thus support trivial copying, alternatively, C++11 move semantics may help here) I attempted a few approaches to implementing bifurcation within the existing state-update framework, but they were messy and thus likely buggy; a proper implementation would rework state-updating to generate copies, but this would be a major change, and seems too late for GCC 11. As a workaround, this patch implements enough of realloc(3) to suppress the false positives. This fixes the false positives in PR analyzer/99193. I've filed PR analyzer/99260 to track "properly" implementing realloc(3). gcc/analyzer/ChangeLog: PR analyzer/99193 * region-model-impl-calls.cc (region_model::impl_call_realloc): New. * region-model.cc (region_model::on_call_pre): Call it. * region-model.h (region_model::impl_call_realloc): New decl. * sm-malloc.cc (enum wording): Add WORDING_REALLOCATED. (malloc_state_machine::m_realloc): New field. (use_after_free::describe_state_change): Add case for WORDING_REALLOCATED. (use_after_free::describe_final_event): Likewise. (malloc_state_machine::malloc_state_machine): Initialize m_realloc. (malloc_state_machine::on_stmt): Handle realloc by calling... (malloc_state_machine::on_realloc_call): New. gcc/testsuite/ChangeLog: PR analyzer/99193 * gcc.dg/analyzer/pr99193-1.c: New test. * gcc.dg/analyzer/pr99193-2.c: New test. * gcc.dg/analyzer/pr99193-3.c: New test. * gcc.dg/analyzer/realloc-1.c: New test.
2021-02-23Daily bump.GCC Administrator1-0/+14
2021-02-22analyzer: handle error/error_at_line [PR99196]David Malcolm4-4/+69
PR analyzer/99196 describes a false positive from -fanalyzer due to the analyzer not "knowing" that calls to GNU libc's error(3) with a nonzero status terminate the process and thus don't return. This patch fixes the false positive by special-casing "error" and "error_at_line". gcc/analyzer/ChangeLog: PR analyzer/99196 * engine.cc (exploded_node::on_stmt): Provide terminate_path flag as a way for on_call_pre to terminate the current analysis path. * region-model-impl-calls.cc (call_details::num_args): New. (region_model::impl_call_error): New. * region-model.cc (region_model::on_call_pre): Add param "out_terminate_path". Handle "error" and "error_at_line". * region-model.h (call_details::num_args): New decl. (region_model::on_call_pre): Add param "out_terminate_path". (region_model::impl_call_error): New decl. gcc/testsuite/ChangeLog: PR analyzer/99196 * gcc.dg/analyzer/error-1.c: New test. * gcc.dg/analyzer/error-2.c: New test. * gcc.dg/analyzer/error-3.c: New test.
2021-02-18Daily bump.GCC Administrator1-0/+40
2021-02-17analyzer: fix false leak involving params [PR98969]David Malcolm6-36/+58
This patch updates the svalue liveness code so that the initial value of parameters at top-level functions to the analysis are treated as live (since the values are presumably still live within the outside-of-the-analysis calling code). This fixes the false leak in PR analyzer/98969 seen on: void test (long int i) { struct foo *f = (struct foo *)i; f->expr = __builtin_malloc (1024); } since the calling code can presumably still access the allocated buffer via: ((struct foo *)i)->expr The patch also removes the expected leak warnings from g++.dg/analyzer/pr99064.C and gcc.dg/analyzer/pr96841.c, which now appear to me to be false positives. gcc/analyzer/ChangeLog: PR analyzer/98969 * constraint-manager.cc (dead_svalue_purger::should_purge_p): Update for change to svalue::live_p. * program-state.cc (sm_state_map::on_liveness_change): Likewise. (program_state::detect_leaks): Likewise. * region-model-reachability.cc (reachable_regions::init_cluster): When dealing with a symbolic region, if the underlying pointer is implicitly live, add the region to the reachable regions. * region-model.cc (region_model::compare_initial_and_pointer): Move logic for detecting initial values of params to initial_svalue::initial_value_of_param_p. * svalue.cc (svalue::live_p): Convert "live_svalues" from a reference to a pointer; support it being NULL. (svalue::implicitly_live_p): Convert first param from a refererence to a pointer. (region_svalue::implicitly_live_p): Likewise. (constant_svalue::implicitly_live_p): Likewise. (initial_svalue::implicitly_live_p): Likewise. Treat the initial values of params for the top level frame as still live. (initial_svalue::initial_value_of_param_p): New function, taken from a test in region_model::compare_initial_and_pointer. (unaryop_svalue::implicitly_live_p): Convert first param from a refererence to a pointer. (binop_svalue::implicitly_live_p): Likewise. (sub_svalue::implicitly_live_p): Likewise. (unmergeable_svalue::implicitly_live_p): Likewise. * svalue.h (svalue::live_p): Likewise. (svalue::implicitly_live_p): Likewise. (region_svalue::implicitly_live_p): Likewise. (constant_svalue::implicitly_live_p): Likewise. (initial_svalue::implicitly_live_p): Likewise. (initial_svalue::initial_value_of_param_p): New decl. (unaryop_svalue::implicitly_live_p): Convert first param from a refererence to a pointer. (binop_svalue::implicitly_live_p): Likewise. (sub_svalue::implicitly_live_p): Likewise. (unmergeable_svalue::implicitly_live_p): Likewise. gcc/testsuite/ChangeLog: PR analyzer/98969 * g++.dg/analyzer/pr99064.C: Convert dg-bogus to dg-warning. * gcc.dg/analyzer/pr96841.c: Add -Wno-analyzer-too-complex to options. Remove false leak directive. * gcc.dg/analyzer/pr98969.c (test_1): Remove xfail from leak false positive. (test_3): New.
2021-02-13Daily bump.GCC Administrator1-0/+27
2021-02-11analyzer: fix ICE in print_mem_ref [PR98969]David Malcolm4-24/+143
PR analyzer/98969 and PR analyzer/99064 describes ICEs, in both cases within print_mem_ref, when falsely reporting memory leaks - though it is possible to generate the ICE on other diagnostics (which I added in one of the test cases). This patch fixes the ICE, leaving the fix for the leak false positives as followup work. The analyzer uses region_model::get_representative_path_var and region_model::get_representative_tree to map back from its svalue and region classes to the tree type used by the rest of the compiler, and, in particular, for diagnostics. The root cause of the ICE is sloppiness about types within those functions; specifically when casts were stripped off svalues. To track these down I added wrapper functions that verify that the types of the results are correct, and in doing so found various other type-safety issues, which the patch also fixes. Doing so led to various changes in diagnostics messages due to more accurate types, but I felt that these changes weren't desirable. For example, the warning at CVE-2005-1689-minimal.c line 48 which expects: double-'free' of 'inbuf.data' changed fo double-'free' of '(char *)inbuf.data' So I added stripping of top-level casts where necessary to avoid cluttering diagnostics. Finally, the more accurate types led to worse results from readability_comparator, where e.g. the event message at line 50 of sensitive-1.c regressed from the precise: passing sensitive value 'password' in call to 'called_by_test_5' from 'test_5' to the vaguer: calling 'called_by_test_5' from 'test_5' This was due to erroneously picking the initial value of "password" in the caller frame as the best value within the *callee* frame, due to "char *" vs "const char *", which confuses the logic for tracking values that pass along callgraph edges. The patch fixes this by combining the readability tests for tree and stack depth, rather than performing them in sequence, so that it favors the value in the deepest frame. As noted above, the patch fixes the ICEs, but does not fix the leak false positives. gcc/analyzer/ChangeLog: PR analyzer/98969 * engine.cc (readability): Add names for the various arbitrary values. Handle NOP_EXPR and INTEGER_CST. (readability_comparator): Combine the readability tests for tree and stack depth, rather than performing them sequentially. (impl_region_model_context::on_state_leak): Strip off top-level casts. * region-model.cc (region_model::get_representative_path_var): Add type-checking, moving the bulk of the implementation to... (region_model::get_representative_path_var_1): ...here. Respect types in casts by recursing and re-adding the cast, rather than merely stripping them off. Use the correct type when handling region_svalue. (region_model::get_representative_tree): Strip off any top-level cast. (region_model::get_representative_path_var): Add type-checking, moving the bulk of the implementation to... (region_model::get_representative_path_var_1): ...here. * region-model.h (region_model::get_representative_path_var_1): New decl (region_model::get_representative_path_var_1): New decl. * store.cc (append_pathvar_with_type): New. (binding_cluster::get_representative_path_vars): Cast path_vars to the correct type when adding them to *OUT_PVS. gcc/testsuite/ChangeLog: PR analyzer/98969 * g++.dg/analyzer/pr99064.C: New test. * gcc.dg/analyzer/pr98969.c: New test.
2021-02-10Daily bump.GCC Administrator1-0/+12
2021-02-09analyzer: support "_IO_"-prefixed variants of FILE * fns [PR98575]David Malcolm1-1/+10
PR analyzer/98575 describes an unexpected -Wanalyzer-malloc-leak false positive from gcc.dg/analyzer/pr94851-1.c on glibc < 2.28. The issue is that a getchar call gets inlined into a call to _IO_getc, and "_IO_getc" is not in the set of FILE * functions the analyzer "knows about". This exposes a bug in memory leak detection on code paths in which an unknown function has been called. The memory leak bug is fixed in the prior commit, but for good measure this patch special-cases the "_IO_"-prefixed names in glibc so that the analyzer can reuse its knowledge about the unprefixed variants. gcc/analyzer/ChangeLog: PR analyzer/98575 * sm-file.cc (is_file_using_fn_p): Support "_IO_"-prefixed variants. gcc/testsuite/ChangeLog: PR analyzer/98575 * gcc.dg/analyzer/file-1.c (test_5): New. * gcc.dg/analyzer/file-3.c: New test.