Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
This patch:
- adds support to the analyzer for tracking API-private state
or which we don't have a decl (such as strtok's internal state),
- uses it to implement a new -Wanalyzer-undefined-behavior-strtok which
warns when strtok (NULL, delim) is called as the first call to
strtok after main.
gcc/analyzer/ChangeLog:
PR analyzer/107573
* analyzer.h (register_known_functions): Add region_model_manager
param.
* analyzer.opt (Wanalyzer-undefined-behavior-strtok): New.
* call-summary.cc
(call_summary_replay::convert_region_from_summary_1): Handle
RK_PRIVATE.
* engine.cc (impl_run_checkers): Pass model manager to
register_known_functions.
* kf.cc (class undefined_function_behavior): New.
(class kf_strtok): New.
(register_known_functions): Add region_model_manager param.
Use it to register "strtok".
* region-model-manager.cc
(region_model_manager::get_or_create_conjured_svalue): Add "idx"
param.
* region-model-manager.h
(region_model_manager::get_or_create_conjured_svalue): Add "idx"
param.
(region_model_manager::get_root_region): New accessor.
* region-model.cc (region_model::scan_for_null_terminator): Handle
"expr" being null.
(region_model::get_representative_path_var_1): Handle RK_PRIVATE.
* region-model.h (region_model::called_from_main_p): Make public.
* region.cc (region::get_memory_space): Handle RK_PRIVATE.
(region::can_have_initial_svalue_p): Handle MEMSPACE_PRIVATE.
(private_region::dump_to_pp): New.
* region.h (MEMSPACE_PRIVATE): New.
(RK_PRIVATE): New.
(class private_region): New.
(is_a_helper <const private_region *>::test): New.
* store.cc (store::replay_call_summary_cluster): Handle
RK_PRIVATE.
* svalue.h (struct conjured_svalue::key_t): Add "idx" param to
ctor and "m_idx" field.
(class conjured_svalue::conjured_svalue): Likewise.
gcc/ChangeLog:
PR analyzer/107573
* doc/invoke.texi: Add -Wanalyzer-undefined-behavior-strtok.
gcc/testsuite/ChangeLog:
PR analyzer/107573
* c-c++-common/analyzer/strtok-1.c: New test.
* c-c++-common/analyzer/strtok-2.c: New test.
* c-c++-common/analyzer/strtok-3.c: New test.
* c-c++-common/analyzer/strtok-4.c: New test.
* c-c++-common/analyzer/strtok-cppreference.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
[PR105948,PR94355]
Fixed spurious possibly-NULL warning always tagging along throwing
operator new despite it never returning NULL.
Now operator new is correctly recognized as possibly returning NULL
if and only if it is non-throwing or exceptions have been disabled.
Different standard signatures of operator new are now properly
recognized.
Added support of placement new, so that it is now properly recognized,
and a 'heap_allocated' region is no longer created for it.
Placement new size is also checked and a 'Wanalyzer-allocation-size'
is emitted when relevant, as well as always a 'Wanalyzer-out-of-bounds'.
'operator new' non-throwing variants are detected y checking the types
of the parameters.
Indeed, in a call to new (std::nothrow) () the chosen overload
has signature 'operator new (void*, std::nothrow_t&)', where the second
parameter is a reference. In a placement new, the second parameter will
always be a void pointer.
Prior to this patch, some buffers first allocated with 'new', then deleted
an thereafter used would result in a 'Wanalyzer-user-after-free'
warning. However the wording was "use after 'free'" instead of the
expected "use after 'delete'".
This patch fixes this by introducing a new kind of poisoned value,
namely POISON_KIND_DELETED.
Due to how the analyzer sees calls to non-throwing variants of
operator new, dereferencing a pointer freshly allocated in this fashion
caused both a 'Wanalyzer-use-of-uninitialized-value' and a
'Wanalyzer-null-dereference' to be emitted, while only the latter was
relevant. As a result, 'null-dereference' now supersedes
'use-of-uninitialized'.
Signed-off-by: benjamin priour <vultkayn@gcc.gnu.org>
gcc/analyzer/ChangeLog:
PR analyzer/105948
PR analyzer/94355
* analyzer.h (is_placement_new_p): New declaration.
* call-details.cc
(call_details::deref_ptr_arg): New function.
Dereference the argument at given index if possible.
* call-details.h: Declaration of the above function.
* kf-lang-cp.cc (is_placement_new_p): Returns true if the gcall
is recognized as a placement new.
(kf_operator_delete::impl_call_post): Unbinding a region and its
descendents now poisons with POISON_KIND_DELETED.
(register_known_functions_lang_cp): Known function "operator
delete" is now registered only once independently of its number of
arguments.
* region-model.cc (region_model::eval_condition): Now
recursively calls itself if any of the operand is wrapped in a
cast.
* sm-malloc.cc (malloc_state_machine::on_stmt):
Add placement new recognition.
* svalue.cc (poison_kind_to_str): Wording for the new PK.
* svalue.h (enum poison_kind): Add value POISON_KIND_DELETED.
gcc/testsuite/ChangeLog:
PR analyzer/105948
PR analyzer/94355
* g++.dg/analyzer/out-of-bounds-placement-new.C: Added a directive.
* g++.dg/analyzer/placement-new.C: Added tests.
* g++.dg/analyzer/new-2.C: New test.
* g++.dg/analyzer/noexcept-new.C: New test.
* g++.dg/analyzer/placement-new-size.C: New test.
|
|
This patch makes -fanalyzer make use of the function attribute
"alloc_size", allowing -fanalyzer to emit -Wanalyzer-allocation-size,
-Wanalyzer-out-of-bounds, and -Wanalyzer-tainted-allocation-size on
execution paths involving allocations using such functions.
gcc/analyzer/ChangeLog:
PR analyzer/110426
* bounds-checking.cc (region_model::check_region_bounds): Handle
symbolic base regions.
* call-details.cc: Include "stringpool.h" and "attribs.h".
(call_details::lookup_function_attribute): New function.
* call-details.h (call_details::lookup_function_attribute): New
function decl.
* region-model-manager.cc
(region_model_manager::maybe_fold_binop): Add reference to
PR analyzer/110902.
* region-model-reachability.cc (reachable_regions::handle_sval):
Add symbolic regions for pointers that are conjured svalues for
the LHS of a stmt.
* region-model.cc (region_model::canonicalize): Purge dynamic
extents for regions that aren't referenced.
(get_result_size_in_bytes): New function.
(region_model::on_call_pre): Use get_result_size_in_bytes and
potentially set the dynamic extents of the region pointed to by
the return value.
(region_model::deref_rvalue): Add param "add_nonnull_constraint"
and use it to conditionalize adding the constraint.
(pending_diagnostic_subclass::dubious_allocation_size): Add "stmt"
param to both ctors and use it to initialize new "m_stmt" field.
(pending_diagnostic_subclass::operator==): Use m_stmt; don't use
m_lhs or m_rhs.
(pending_diagnostic_subclass::m_stmt): New field.
(region_model::check_region_size): Generalize to any kind of
pointer svalue by using deref_rvalue rather than checking for
region_svalue. Pass stmt to dubious_allocation_size ctor.
* region-model.h (region_model::deref_rvalue): Add param
"add_nonnull_constraint".
* svalue.cc (conjured_svalue::lhs_value_p): New function.
* svalue.h (conjured_svalue::lhs_value_p): New decl.
gcc/testsuite/ChangeLog:
PR analyzer/110426
* gcc.dg/analyzer/allocation-size-1.c: Update expected message to
reflect consolidation of size and assignment into a single event.
* gcc.dg/analyzer/allocation-size-2.c: Likewise.
* gcc.dg/analyzer/allocation-size-3.c: Likewise.
* gcc.dg/analyzer/allocation-size-4.c: Likewise.
* gcc.dg/analyzer/allocation-size-multiline-1.c: Likewise.
* gcc.dg/analyzer/allocation-size-multiline-2.c: Likewise.
* gcc.dg/analyzer/allocation-size-multiline-3.c: Likewise.
* gcc.dg/analyzer/attr-alloc_size-1.c: New test.
* gcc.dg/analyzer/attr-alloc_size-2.c: New test.
* gcc.dg/analyzer/attr-alloc_size-3.c: New test.
* gcc.dg/analyzer/explode-4.c: New test.
* gcc.dg/analyzer/taint-size-1.c: Add test coverage for
__attribute__ alloc_size.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
This patch introduces a "symbol" base class that region and svalue
both inherit from, generalizing the ID from the region class so it's
also used by svalues. This gives a way of sorting regions and svalues
into creation order, which I've found useful in my experiments with
adding SMT support (PR analyzer/104940).
gcc/ChangeLog:
PR analyzer/104940
* Makefile.in (ANALYZER_OBJS): Add analyzer/symbol.o.
gcc/analyzer/ChangeLog:
PR analyzer/104940
* region-model-manager.cc
(region_model_manager::region_model_manager): Update for
generalizing region ids to also cover svalues.
(region_model_manager::get_or_create_constant_svalue): Likewise.
(region_model_manager::get_or_create_unknown_svalue): Likewise.
(region_model_manager::create_unique_svalue): Likewise.
(region_model_manager::get_or_create_initial_value): Likewise.
(region_model_manager::get_or_create_setjmp_svalue): Likewise.
(region_model_manager::get_or_create_poisoned_svalue): Likewise.
(region_model_manager::get_ptr_svalue): Likewise.
(region_model_manager::get_or_create_unaryop): Likewise.
(region_model_manager::get_or_create_binop): Likewise.
(region_model_manager::get_or_create_sub_svalue): Likewise.
(region_model_manager::get_or_create_repeated_svalue): Likewise.
(region_model_manager::get_or_create_bits_within): Likewise.
(region_model_manager::get_or_create_unmergeable): Likewise.
(region_model_manager::get_or_create_widening_svalue): Likewise.
(region_model_manager::get_or_create_compound_svalue): Likewise.
(region_model_manager::get_or_create_conjured_svalue): Likewise.
(region_model_manager::get_or_create_asm_output_svalue): Likewise.
(region_model_manager::get_or_create_const_fn_result_svalue):
Likewise.
(region_model_manager::get_region_for_fndecl): Likewise.
(region_model_manager::get_region_for_label): Likewise.
(region_model_manager::get_region_for_global): Likewise.
(region_model_manager::get_field_region): Likewise.
(region_model_manager::get_element_region): Likewise.
(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_frame_region): Likewise.
(region_model_manager::get_symbolic_region): Likewise.
(region_model_manager::get_region_for_string): Likewise.
(region_model_manager::get_bit_range): Likewise.
(region_model_manager::get_var_arg_region): Likewise.
(region_model_manager::get_region_for_unexpected_tree_code):
Likewise.
(region_model_manager::get_or_create_region_for_heap_alloc):
Likewise.
(region_model_manager::create_region_for_alloca): Likewise.
(region_model_manager::log_stats): Likewise.
* region-model-manager.h (region_model_manager::get_num_regions):
Replace with...
(region_model_manager::get_num_symbols): ...this.
(region_model_manager::alloc_region_id): Replace with...
(region_model_manager::alloc_symbol_id): ...this.
(region_model_manager::m_next_region_id): Replace with...
(region_model_manager::m_next_symbol_id): ...this.
* region-model.cc (selftest::test_get_representative_tree): Update
for generalizing region ids to also cover svalues.
(selftest::test_binop_svalue_folding): Likewise.
(selftest::test_state_merging): Likewise.
* region.cc (region::cmp_ids): Delete, in favor of
symbol::cmp_ids.
(region::region): Update for introduction of symbol base class.
(frame_region::get_region_for_local): Likewise.
(root_region::root_region): Likewise.
(symbolic_region::symbolic_region): Likewise.
* region.h: Replace include of "analyzer/complexity.h" with
"analyzer/symbol.h".
(class region): Make a subclass of symbol.
(region::get_id): Delete in favor of symbol::get_id.
(region::cmp_ids): Delete in favor of symbol::cmp_ids.
(region::get_complexity): Delete in favor of
symbol::get_complexity.
(region::region): Use symbol::id_t for "id" param.
(region::m_complexity): Move field to symbol base class.
(region::m_id): Likewise.
(space_region::space_region): Use symbol::id_t for "id" param.
(frame_region::frame_region): Likewise.
(globals_region::globals_region): Likewise.
(code_region::code_region): Likewise.
(function_region::function_region): Likewise.
(label_region::label_region): Likewise.
(stack_region::stack_region): Likewise.
(heap_region::heap_region): Likewise.
(thread_local_region::thread_local_region): Likewise.
(root_region::root_region): Likewise.
(symbolic_region::symbolic_region): Likewise.
(decl_region::decl_region): Likewise.
(field_region::field_region): Likewise.
(element_region::element_region): Likewise.
(offset_region::offset_region): Likewise.
(sized_region::sized_region): Likewise.
(cast_region::cast_region): Likewise.
(heap_allocated_region::heap_allocated_region): Likewise.
(alloca_region::alloca_region): Likewise.
(string_region::string_region): Likewise.
(bit_range_region::bit_range_region): Likewise.
(var_arg_region::var_arg_region): Likewise.
(errno_region::errno_region): Likewise.
(unknown_region::unknown_region): Likewise.
* svalue.cc (sub_svalue::sub_svalue): Add symbol::id_t param.
(repeated_svalue::repeated_svalue): Likewise.
(bits_within_svalue::bits_within_svalue): Likewise.
(compound_svalue::compound_svalue): Likewise.
* svalue.h: Replace include of "analyzer/complexity.h" with
"analyzer/symbol.h".
(class svalue): Make a subclass of symbol.
(svalue::get_complexity): Delete in favor of
symbol::get_complexity.
(svalue::svalue): Add symbol::id_t param. Update for new base
class.
(svalue::m_complexity): Delete in favor of
symbol::m_complexity.
(region_svalue::region_svalue): Add symbol::id_t param
(constant_svalue::constant_svalue): Likewise.
(unknown_svalue::unknown_svalue): Likewise.
(poisoned_svalue::poisoned_svalue): Likewise.
(setjmp_svalue::setjmp_svalue): Likewise.
(initial_svalue::initial_svalue): Likewise.
(unaryop_svalue::unaryop_svalue): Likewise.
(binop_svalue::binop_svalue): Likewise.
(sub_svalue::sub_svalue): Likewise.
(repeated_svalue::repeated_svalue): Likewise.
(bits_within_svalue::bits_within_svalue): Likewise.
(unmergeable_svalue::unmergeable_svalue): Likewise.
(placeholder_svalue::placeholder_svalue): Likewise.
(widening_svalue::widening_svalue): Likewise.
(compound_svalue::compound_svalue): Likewise.
(conjured_svalue::conjured_svalue): Likewise.
(asm_output_svalue::asm_output_svalue): Likewise.
(const_fn_result_svalue::const_fn_result_svalue): Likewise.
* symbol.cc: New file.
* symbol.h: New file.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
|
|
gcc/analyzer/ChangeLog:
* analysis-plan.cc: Simplify includes.
* analyzer-pass.cc: Likewise.
* analyzer-selftests.cc: Likewise.
* analyzer.cc: Likewise.
* analyzer.h: Add includes of "json.h" and "tristate.h".
* call-info.cc: Simplify includes.
* call-string.cc: Likewise.
* call-summary.cc: Likewise.
* checker-path.cc: Likewise.
* complexity.cc: Likewise.
* constraint-manager.cc: Likewise.
* diagnostic-manager.cc: Likewise.
* engine.cc: Likewise.
* feasible-graph.cc: Likewise.
* known-function-manager.cc: Likewise.
* pending-diagnostic.cc: Likewise.
* program-point.cc: Likewise.
* program-state.cc: Likewise.
* region-model-asm.cc: Likewise.
* region-model-impl-calls.cc: Likewise.
* region-model-manager.cc: Likewise.
* region-model-reachability.cc: Likewise.
* region-model.cc: Likewise.
* region-model.h: Include "selftest.h".
* region.cc: Simplify includes.
* sm-fd.cc: 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.
* sm.cc: Likewise.
* state-purge.cc: Likewise.
* store.cc: Likewise.
* store.h: Likewise.
* supergraph.cc: Likewise.
* svalue.cc: Likewise.
* svalue.h: Likewise.
* trimmed-graph.cc: Likewise.
* varargs.cc: Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
With -fanalyzer-call-summaries the analyzer canl attempt to summarize
the effects of some function calls at their call site, rather than
simulate the call directly, which can avoid big slowdowns during
analysis.
Previously, this summarization was extremely simplistic: no attempt
was made to update sm-state, and region_model::update_for_call_summary
would simply set the return value of the function to UNKNOWN, and assume
the function had no side effects.
This patch implements less simplistic summarizations: it tracks each
possible return enode from the called function, and attempts to generate
a successor enode from the callsite for each that have compatible
conditions, mapping state changes in the summary to state changes
at the callsite. It also implements the beginnings of heuristics for
generating user-facing descriptions of a summary e.g.
"when 'foo' returns NULL"
versus:
"when 'foo' returns a heap-allocated buffer"
This still has some bugs, but much more accurately tracks the effects
of a call, and so is an improvement; it should only have an effect
when -fanalyzer-call-summaries is enabled.
As before, -fanalyzer-call-summaries is disabled by default in
analyzer.opt (but enabled by default in the test suite).
gcc/ChangeLog:
PR analyzer/107072
* Makefile.in (ANALYZER_OBJS): Add analyzer/call-summary.o.
gcc/analyzer/ChangeLog:
PR analyzer/107072
* analyzer-logging.h: Include "diagnostic-core.h".
* analyzer.h: Include "function.h".
(class call_summary): New forward decl.
(class call_summary_replay): New forward decl.
(struct per_function_data): New forward decl.
(struct interesting_t): New forward decl.
(custom_edge_info::update_state): New vfunc.
* call-info.cc (custom_edge_info::update_state): New.
* call-summary.cc: New file.
* call-summary.h: New file.
* constraint-manager.cc: Include "analyzer/call-summary.h".
(class replay_fact_visitor): New.
(constraint_manager::replay_call_summary): New.
* constraint-manager.h (constraint_manager::replay_call_summary):
New.
* engine.cc: Include "analyzer/call-summary.h".
(exploded_node::on_stmt): Handle call summaries.
(class call_summary_edge_info): New.
(exploded_node::replay_call_summaries): New.
(exploded_node::replay_call_summary): New.
(per_function_data::~per_function_data): New.
(per_function_data::add_call_summary): Move here from header and
reimplement.
(exploded_graph::process_node): Call update_state rather than
update_model when handling bifurcation
(viz_callgraph_node::dump_dot): Use a regular label rather
than an HTML table; add summaries to dump.
* exploded-graph.h: Include "alloc-pool.h", "fibonacci_heap.h",
"supergraph.h", "sbitmap.h", "shortest-paths.h", "analyzer/sm.h",
"analyzer/program-state.h", and "analyzer/diagnostic-manager.h".
(exploded_node::replay_call_summaries): New decl.
(exploded_node::replay_call_summary): New decl.
(per_function_data::~per_function_data): New decl.
(per_function_data::add_call_summary): Move implemention from
header.
(per_function_data::m_summaries): Update type of element.
* known-function-manager.h: Include "analyzer/analyzer-logging.h".
* program-point.h: Include "pretty-print.h" and
"analyzer/call-string.h".
* program-state.cc: Include "analyzer/call-summary.h".
(sm_state_map::replay_call_summary): New.
(program_state::replay_call_summary): New.
* program-state.h (sm_state_map::replay_call_summary): New decl.
(program_state::replay_call_summary): New decl.
* region-model-manager.cc
(region_model_manager::get_or_create_asm_output_svalue): New
overload.
* region-model-manager.h
(region_model_manager::get_or_create_asm_output_svalue): New
overload decl.
* region-model.cc: Include "analyzer/call-summary.h".
(region_model::maybe_update_for_edge): Remove call to
region_model::update_for_call_summary on
SUPEREDGE_INTRAPROCEDURAL_CALL.
(region_model::update_for_call_summary): Delete.
(region_model::replay_call_summary): New.
* region-model.h (region_model::replay_call_summary): New decl.
(region_model::update_for_call_summary): Delete decl.
* store.cc: Include "analyzer/call-summary.h".
(store::replay_call_summary): New.
(store::replay_call_summary_cluster): New.
* store.h: Include "tristate.h".
(is_a_helper <const ana::concrete_binding *>::test): New.
(store::replay_call_summary): New decl.
(store::replay_call_summary_cluster): New decl.
* supergraph.cc (get_ultimate_function_for_cgraph_edge): Remove
"static" from decl.
(supergraph_call_edge): Make stmt param const.
* supergraph.h: Include "ordered-hash-map.h", "cfg.h",
"basic-block.h", "gimple.h", "gimple-iterator.h", and "digraph.h".
(supergraph_call_edge): Make stmt param const.
(get_ultimate_function_for_cgraph_edge): New decl.
* svalue.cc (compound_svalue::compound_svalue): Assert that we're
not nesting compound_svalues.
* svalue.h: Include "json.h", "analyzer/store.h", and
"analyzer/program-point.h".
(asm_output_svalue::get_num_outputs): New accessor.
gcc/testsuite/ChangeLog:
PR analyzer/107072
* gcc.dg/analyzer/call-summaries-2.c: New test.
* gcc.dg/analyzer/call-summaries-3.c: New test.
* gcc.dg/analyzer/call-summaries-asm-x86.c: New test.
* gcc.dg/analyzer/call-summaries-malloc.c: New test.
* gcc.dg/analyzer/call-summaries-pr107072.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
Enabling work towrads better call summarization.
gcc/analyzer/ChangeLog:
* region-model-manager.cc
(region_model_manager::get_or_create_widening_svalue): Use a
function_point rather than a program_point.
* region-model.cc (selftest::test_widening_constraints): Likewise.
* region-model.h
(region_model_manager::get_or_create_widening_svalue): Likewise.
(model_merger::get_function_point): New.
* svalue.cc (svalue::can_merge_p): Use a function_point rather
than a program_point.
(svalue::can_merge_p): Likewise.
* svalue.h (widening_svalue::key_t): Likewise.
(widening_svalue::widening_svalue): Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
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>
|
|
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>
|
|
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>
|
|
When testing -fanalyzer on openblas-0.3, I noticed slightly over 2000
false positives from -Wanalyzer-malloc-leak on code like this:
if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) {
pt_t = (lapack_complex_float*)
LAPACKE_malloc( sizeof(lapack_complex_float) *
ldpt_t * MAX(1,n) );
[...snip...]
}
[...snip lots of code...]
if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'q' ) ) {
LAPACKE_free( pt_t );
}
where LAPACKE_lsame is a char-comparison function implemented in a
different TU.
The analyzer naively considers the execution path where:
LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' )
is true at the malloc guard, but then false at the free guard, which
is thus a memory leak.
This patch makes -fanalyer respect __attribute__((const)), so that the
analyzer treats such functions as returning the same value when given
the same inputs.
I've filed https://github.com/xianyi/OpenBLAS/issues/3543 suggesting that
LAPACKE_lsame be annotated with __attribute__((const)); with that, and
with this patch, the false positives seem to be fixed.
gcc/analyzer/ChangeLog:
PR analyzer/104434
* analyzer.h (class const_fn_result_svalue): New decl.
* region-model-impl-calls.cc (call_details::get_manager): New.
* region-model-manager.cc
(region_model_manager::get_or_create_const_fn_result_svalue): New.
(region_model_manager::log_stats): Log
m_const_fn_result_values_map.
* region-model.cc (const_fn_p): New.
(maybe_get_const_fn_result): New.
(region_model::on_call_pre): Handle fndecls with
__attribute__((const)) by calling the above rather than making
a conjured_svalue.
* region-model.h (visitor::visit_const_fn_result_svalue): New.
(region_model_manager::get_or_create_const_fn_result_svalue): New
decl.
(region_model_manager::const_fn_result_values_map_t): New typedef.
(region_model_manager::m_const_fn_result_values_map): New field.
(call_details::get_manager): New decl.
* svalue.cc (svalue::cmp_ptr): Handle SK_CONST_FN_RESULT.
(const_fn_result_svalue::dump_to_pp): New.
(const_fn_result_svalue::dump_input): New.
(const_fn_result_svalue::accept): New.
* svalue.h (enum svalue_kind): Add SK_CONST_FN_RESULT.
(svalue::dyn_cast_const_fn_result_svalue): New.
(class const_fn_result_svalue): New.
(is_a_helper <const const_fn_result_svalue *>::test): New.
(template <> struct default_hash_traits<const_fn_result_svalue::key_t>):
New.
gcc/testsuite/ChangeLog:
PR analyzer/104434
* gcc.dg/analyzer/attr-const-1.c: New test.
* gcc.dg/analyzer/attr-const-2.c: New test.
* gcc.dg/analyzer/attr-const-3.c: New test.
* gcc.dg/analyzer/pr104434-const.c: New test.
* gcc.dg/analyzer/pr104434-nonconst.c: New test.
* gcc.dg/analyzer/pr104434.h: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
|
|
gcc/ChangeLog:
PR analyzer/101570
* Makefile.in (ANALYZER_OBJS): Add analyzer/region-model-asm.o.
gcc/analyzer/ChangeLog:
PR analyzer/101570
* analyzer.cc (maybe_reconstruct_from_def_stmt): Add GIMPLE_ASM
case.
* analyzer.h (class asm_output_svalue): New forward decl.
(class reachable_regions): New forward decl.
* complexity.cc (complexity::from_vec_svalue): New.
* complexity.h (complexity::from_vec_svalue): New decl.
* engine.cc (feasibility_state::maybe_update_for_edge): Handle
asm stmts by calling on_asm_stmt.
* region-model-asm.cc: New file.
* region-model-manager.cc
(region_model_manager::maybe_fold_asm_output_svalue): New.
(region_model_manager::get_or_create_asm_output_svalue): New.
(region_model_manager::log_stats): Log m_asm_output_values_map.
* region-model.cc (region_model::on_stmt_pre): Handle GIMPLE_ASM.
* region-model.h (visitor::visit_asm_output_svalue): New.
(region_model_manager::get_or_create_asm_output_svalue): New decl.
(region_model_manager::maybe_fold_asm_output_svalue): New decl.
(region_model_manager::asm_output_values_map_t): New typedef.
(region_model_manager::m_asm_output_values_map): New field.
(region_model::on_asm_stmt): New.
* store.cc (binding_cluster::on_asm): New.
* store.h (binding_cluster::on_asm): New decl.
* svalue.cc (svalue::cmp_ptr): Handle SK_ASM_OUTPUT.
(asm_output_svalue::dump_to_pp): New.
(asm_output_svalue::dump_input): New.
(asm_output_svalue::input_idx_to_asm_idx): New.
(asm_output_svalue::accept): New.
* svalue.h (enum svalue_kind): Add SK_ASM_OUTPUT.
(svalue::dyn_cast_asm_output_svalue): New.
(class asm_output_svalue): New.
(is_a_helper <const asm_output_svalue *>::test): New.
(struct default_hash_traits<asm_output_svalue::key_t>): New.
gcc/testsuite/ChangeLog:
PR analyzer/101570
* gcc.dg/analyzer/asm-x86-1.c: New test.
* gcc.dg/analyzer/asm-x86-lp64-1.c: New test.
* gcc.dg/analyzer/asm-x86-lp64-2.c: New test.
* gcc.dg/analyzer/pr101570.c: New test.
* gcc.dg/analyzer/torture/asm-x86-linux-array_index_mask_nospec.c:
New test.
* gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-1.c: New
test.
* gcc.dg/analyzer/torture/asm-x86-linux-cpuid-paravirt-2.c: New
test.
* gcc.dg/analyzer/torture/asm-x86-linux-cpuid.c: New test.
* gcc.dg/analyzer/torture/asm-x86-linux-rdmsr-paravirt.c: New
test.
* gcc.dg/analyzer/torture/asm-x86-linux-rdmsr.c: New test.
* gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-full.c:
New test.
* gcc.dg/analyzer/torture/asm-x86-linux-wfx_get_ps_timeout-reduced.c:
New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
PR analyzer/101503 reports an assertion failure due to an unexpected
"UNKNOWN" value (due to using --param analyzer-max-svalue-depth=0).
This patch fixes this by rejecting attempts to purge state involving
unknown/poisoned svalues (in region_model::purge_state_involving),
as these svalues should not have state associated with them - they
are singletons w.r.t each type.
To be more systematic about this, the patch also introduces a new
svalue::can_have_associated_state_p which returns false for
unknown/poisoned svalues, so that we can reject adding constraints
or sm-state on them, or building various kinds of svalue in terms
of them (e.g. unary ops, binary ops, etc).
gcc/analyzer/ChangeLog:
PR analyzer/101503
* constraint-manager.cc (constraint_manager::add_constraint): Use
can_have_associated_state_p rather than testing for unknown.
(constraint_manager::get_or_add_equiv_class): Likewise.
* program-state.cc (sm_state_map::set_state): Likewise.
(sm_state_map::impl_set_state): Add assertion.
* region-model-manager.cc
(region_model_manager::maybe_fold_unaryop): Handle poisoned
values.
(region_model_manager::maybe_fold_binop): Move handling of unknown
values...
(region_model_manager::get_or_create_binop): ...to here, and
generalize to use can_have_associated_state_p.
(region_model_manager::maybe_fold_sub_svalue): Use
can_have_associated_state_p rather than testing for unknown.
(region_model_manager::maybe_fold_repeated_svalue): Use unknown
when the size or repeated value is "unknown"/"poisoned".
* region-model.cc (region_model::purge_state_involving): Reject
attempts to purge unknown/poisoned svalues, as these svalues
should not have state associated with them.
* svalue.cc (sub_svalue::sub_svalue): Assert that we're building
on top of an svalue with can_have_associated_state_p.
(repeated_svalue::repeated_svalue): Likewise.
(bits_within_svalue::bits_within_svalue): Likewise.
* svalue.h (svalue::can_have_associated_state_p): New.
(unknown_svalue::can_have_associated_state_p): New.
(poisoned_svalue::can_have_associated_state_p): New.
(unaryop_svalue::unaryop_svalue): Assert that we're building on
top of an svalue with can_have_associated_state_p.
(binop_svalue::binop_svalue): Likewise.
(widening_svalue::widening_svalue): Likewise.
gcc/testsuite/ChangeLog:
PR analyzer/101503
* gcc.dg/analyzer/pr101503.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
gcc/analyzer/ChangeLog:
* program-state.cc (program_state::detect_leaks): Simplify using
svalue::maybe_get_region.
* region-model-impl-calls.cc (region_model::impl_call_fgets): Likewise.
(region_model::impl_call_fread): Likewise.
(region_model::impl_call_free): Likewise.
(region_model::impl_call_operator_delete): Likewise.
* region-model.cc (selftest::test_stack_frames): Likewise.
(selftest::test_state_merging): Likewise.
* svalue.cc (svalue::maybe_get_region): New.
* svalue.h (svalue::maybe_get_region): New decl.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
gcc/analyzer/ChangeLog:
* svalue.h (is_a_helper <placeholder_svalue *>::test): Make
param and template param const.
(is_a_helper <widening_svalue *>::test): Likewise.
(is_a_helper <compound_svalue *>::test): Likewise.
(is_a_helper <conjured_svalue *>::test): Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
The initial gcc 10 era commit of the analyzer (in
757bf1dff5e8cee34c0a75d06140ca972bfecfa7) had an implementation of
-Wanalyzer-use-of-uninitialized-value, but was sufficiently buggy
that I removed it in 78b9783774bfd3540f38f5b1e3c7fc9f719653d7 before
the release of gcc 10.1
This patch reintroduces the warning, heavily rewritten, with (I hope)
a less buggy implementation this time, for GCC 12.
gcc/analyzer/ChangeLog:
PR analyzer/95006
PR analyzer/94713
PR analyzer/94714
* analyzer.cc (maybe_reconstruct_from_def_stmt): Split out
GIMPLE_ASSIGN case into...
(get_diagnostic_tree_for_gassign_1): New.
(get_diagnostic_tree_for_gassign): New.
* analyzer.h (get_diagnostic_tree_for_gassign): New decl.
* analyzer.opt (Wanalyzer-write-to-string-literal): New.
* constraint-manager.cc (class svalue_purger): New.
(constraint_manager::purge_state_involving): New.
* constraint-manager.h
(constraint_manager::purge_state_involving): New.
* diagnostic-manager.cc (saved_diagnostic::supercedes_p): New.
(dedupe_winners::handle_interactions): New.
(diagnostic_manager::emit_saved_diagnostics): Call it.
* diagnostic-manager.h (saved_diagnostic::supercedes_p): New decl.
* engine.cc (impl_region_model_context::warn): Convert return type
to bool. Return false if the diagnostic isn't saved.
(impl_region_model_context::purge_state_involving): New.
(impl_sm_context::get_state): Use NULL ctxt when querying old
rvalue.
(impl_sm_context::set_next_state): Use new sval when querying old
state.
(class dump_path_diagnostic): Move to region-model.cc
(exploded_node::on_stmt): Move to on_stmt_pre and on_stmt_post.
Remove call to purge_state_involving.
(exploded_node::on_stmt_pre): New, based on the above. Move most
of it to region_model::on_stmt_pre.
(exploded_node::on_stmt_post): Likewise, moving to
region_model::on_stmt_post.
(class stale_jmp_buf): Fix parent class to use curiously recurring
template pattern.
(feasibility_state::maybe_update_for_edge): Call on_call_pre and
on_call_post on gcalls.
* exploded-graph.h (impl_region_model_context::warn): Return bool.
(impl_region_model_context::purge_state_involving): New decl.
(exploded_node::on_stmt_pre): New decl.
(exploded_node::on_stmt_post): New decl.
* pending-diagnostic.h (pending_diagnostic::use_of_uninit_p): New.
(pending_diagnostic::supercedes_p): New.
* program-state.cc (sm_state_map::get_state): Inherit state for
conjured_svalue as well as initial_svalue.
(sm_state_map::purge_state_involving): Also support SK_CONJURED.
* region-model-impl-calls.cc (call_details::get_uncertainty):
Handle m_ctxt being NULL.
(call_details::get_or_create_conjured_svalue): New.
(region_model::impl_call_fgets): New.
(region_model::impl_call_fread): New.
* region-model-manager.cc
(region_model_manager::get_or_create_initial_value): Return an
uninitialized poisoned value for regions that can't have initial
values.
* region-model-reachability.cc
(reachable_regions::mark_escaped_clusters): Handle ctxt being
NULL.
* region-model.cc (region_to_value_map::purge_state_involving): New.
(poisoned_value_diagnostic::use_of_uninit_p): New.
(poisoned_value_diagnostic::emit): Handle POISON_KIND_UNINIT.
(poisoned_value_diagnostic::describe_final_event): Likewise.
(region_model::check_for_poison): New.
(region_model::on_assignment): Call it.
(class dump_path_diagnostic): Move here from engine.cc.
(region_model::on_stmt_pre): New, based on exploded_node::on_stmt.
(region_model::on_call_pre): Move the setting of the LHS to a
conjured svalue to before the checks for specific functions.
Handle "fgets", "fgets_unlocked", and "fread".
(region_model::purge_state_involving): New.
(region_model::handle_unrecognized_call): Handle ctxt being NULL.
(region_model::get_rvalue): Call check_for_poison.
(selftest::test_stack_frames): Use NULL for context when getting
uninitialized rvalue.
(selftest::test_alloca): Likewise.
* region-model.h (region_to_value_map::purge_state_involving): New
decl.
(call_details::get_or_create_conjured_svalue): New decl.
(region_model::on_stmt_pre): New decl.
(region_model::purge_state_involving): New decl.
(region_model::impl_call_fgets): New decl.
(region_model::impl_call_fread): New decl.
(region_model::check_for_poison): New decl.
(region_model_context::warn): Return bool.
(region_model_context::purge_state_involving): New.
(noop_region_model_context::warn): Return bool.
(noop_region_model_context::purge_state_involving): New.
(test_region_model_context:: warn): Return bool.
* region.cc (region::get_memory_space): New.
(region::can_have_initial_svalue_p): New.
(region::involves_p): New.
* region.h (enum memory_space): New.
(region::get_memory_space): New decl.
(region::can_have_initial_svalue_p): New decl.
(region::involves_p): New decl.
* sm-malloc.cc (use_after_free::supercedes_p): New.
* store.cc (binding_cluster::purge_state_involving): New.
(store::purge_state_involving): New.
* store.h (class symbolic_binding): New forward decl.
(binding_key::dyn_cast_symbolic_binding): New.
(symbolic_binding::dyn_cast_symbolic_binding): New.
(binding_cluster::purge_state_involving): New.
(store::purge_state_involving): New.
* svalue.cc (svalue::can_merge_p): Reject attempts to merge
poisoned svalues with other svalues, so that we identify
paths in which a variable is conditionally uninitialized.
(involvement_visitor::visit_conjured_svalue): New.
(svalue::involves_p): Also handle SK_CONJURED.
(poison_kind_to_str): Handle POISON_KIND_UNINIT.
(poisoned_svalue::maybe_fold_bits_within): New.
* svalue.h (enum poison_kind): Add POISON_KIND_UNINIT.
(poisoned_svalue::maybe_fold_bits_within): New decl.
gcc/ChangeLog:
PR analyzer/95006
PR analyzer/94713
PR analyzer/94714
* doc/invoke.texi: Add -Wanalyzer-use-of-uninitialized-value.
gcc/testsuite/ChangeLog:
PR analyzer/95006
PR analyzer/94713
PR analyzer/94714
* g++.dg/analyzer/pr93212.C: Update location of warning.
* g++.dg/analyzer/pr94011.C: Add
-Wno-analyzer-use-of-uninitialized-value.
* g++.dg/analyzer/pr94503.C: Likewise.
* gcc.dg/analyzer/clobbers-1.c: Convert "f" from a local to a
param to avoid uninitialized warning.
* gcc.dg/analyzer/data-model-1.c (test_12): Add test for
uninitialized value on result of alloca.
(test_12a): Add expected warning.
(test_12c): Likewise.
(test_19): Likewise.
(test_29b): Likewise.
(test_29c): Likewise.
(test_37): Remove xfail.
(test_37a): Likewise.
* gcc.dg/analyzer/data-model-20.c: Add warning about leak.
* gcc.dg/analyzer/explode-2.c: Remove params; add
-Wno-analyzer-too-complex, -Wno-analyzer-malloc-leak, and xfails.
Initialize the locals.
* gcc.dg/analyzer/explode-2a.c: Initialize the locals. Add
expected leak.
* gcc.dg/analyzer/fgets-1.c: New test.
* gcc.dg/analyzer/fread-1.c: New test.
* gcc.dg/analyzer/malloc-1.c (test_16): Add expected warning.
(test_40): Likewise.
* gcc.dg/analyzer/memset-CVE-2017-18549-1.c: Check for
uninitialized padding.
* gcc.dg/analyzer/pr93355-localealias-feasibility.c (fread): New
decl.
(read_alias_file): Call it.
* gcc.dg/analyzer/pr94047.c: Add expected warnings.
* gcc.dg/analyzer/pr94851-2.c: Likewise.
* gcc.dg/analyzer/pr96841.c: Convert local to a param.
* gcc.dg/analyzer/pr98628.c: Likewise.
* gcc.dg/analyzer/pr99042.c: Updated expected location of leak
diagnostics.
* gcc.dg/analyzer/symbolic-1.c: Add expected warnings.
* gcc.dg/analyzer/symbolic-7.c: Likewise.
* gcc.dg/analyzer/torture/pr93649.c: Add expected warning. Skip
with -fno-fat-lto-objects.
* gcc.dg/analyzer/uninit-1.c: New test.
* gcc.dg/analyzer/uninit-2.c: New test.
* gcc.dg/analyzer/uninit-3.c: New test.
* gcc.dg/analyzer/uninit-4.c: New test.
* gcc.dg/analyzer/uninit-pr94713.c: New test.
* gcc.dg/analyzer/uninit-pr94714.c: New test.
* gcc.dg/analyzer/use-after-free-2.c: New test.
* gcc.dg/analyzer/use-after-free-3.c: New test.
* gcc.dg/analyzer/zlib-3.c: Add expected warning.
* gcc.dg/analyzer/zlib-6.c: Convert locals to params to avoid
uninitialized warnings. Remove xfail.
* gcc.dg/analyzer/zlib-6a.c: New test, based on the old version
of the above.
* gfortran.dg/analyzer/pr97668.f: Add
-Wno-analyzer-use-of-uninitialized-value and
-Wno-analyzer-too-complex.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
I'm working on reimplementing -Wanalyzer-use-of-uninitialized-value, but
I ran into issues with
region_model::add_any_constraints_from_ssa_def_stmt.
This function is from the initial commit of the analyzer and walks the
SSA names finding conditions that were missed due to the GCC 10 era
region_model not retaining useful information on how values were
created; as of GCC 11 the symbolic values contain this information,
and so the conditions can be reconstructed from them instead.
region_model::add_any_constraints_from_ssa_def_stmt is a liability
when tracking uninitialized values as it requires looking up SSA
values when those values may have been purged, thus greatly complicating
detection of uses of uninitialized values.
It's simplest to eliminate it and reimplement the condition-finding
via the makeup of the svalues, which this patch does. Doing so requires
supporting add_condition on svalues rather than just on trees, which
requires some changes to ana::state_machine and its subclasses.
gcc/analyzer/ChangeLog:
* diagnostic-manager.cc (null_assignment_sm_context::get_state):
New overload.
(null_assignment_sm_context::set_next_state): New overload.
(null_assignment_sm_context::get_diagnostic_tree): New.
* engine.cc (impl_sm_context::get_state): New overload.
(impl_sm_context::set_next_state): New overload.
(impl_sm_context::get_diagnostic_tree): New overload.
(impl_region_model_context::on_condition): Convert params from
tree to const svalue *.
* exploded-graph.h (impl_region_model_context::on_condition):
Likewise.
* region-model.cc (region_model::on_call_pre): Move handling of
internal calls to before checking for get_fndecl_for_call.
(region_model::add_constraints_from_binop): New.
(region_model::add_constraint): Split out into a new overload
working on const svalue * rather than tree. Call
add_constraints_from_binop. Drop call to
add_any_constraints_from_ssa_def_stmt.
(region_model::add_any_constraints_from_ssa_def_stmt): Delete.
(region_model::add_any_constraints_from_gassign): Delete.
(region_model::add_any_constraints_from_gcall): Delete.
* region-model.h
(region_model::add_any_constraints_from_ssa_def_stmt): Delete.
(region_model::add_any_constraints_from_gassign): Delete.
(region_model::add_any_constraints_from_gcall): Delete.
(region_model::add_constraint): Add overload decl.
(region_model::add_constraints_from_binop): New decl.
(region_model_context::on_condition): Convert params from tree to
const svalue *.
(noop_region_model_context::on_condition): Likewise.
* sm-file.cc (fileptr_state_machine::condition): Likewise.
* sm-malloc.cc (malloc_state_machine::on_condition): Likewise.
* sm-pattern-test.cc: Include tristate.h, selftest.h,
analyzer/call-string.h, analyzer/program-point.h,
analyzer/store.h, and analyzer/region-model.h.
(pattern_test_state_machine::on_condition): Convert params from tree to
const svalue *.
* sm-sensitive.cc (sensitive_state_machine::on_condition): Delete.
* sm-signal.cc (signal_state_machine::on_condition): Delete.
* sm-taint.cc (taint_state_machine::on_condition): Convert params
from tree to const svalue *.
* sm.cc: Include tristate.h, selftest.h, analyzer/call-string.h,
analyzer/program-point.h, analyzer/store.h, and
analyzer/region-model.h.
(any_pointer_p): Add overload taking const svalue *sval.
* sm.h (any_pointer_p): Add overload taking const svalue *sval.
(state_machine::on_condition): Convert params from tree to
const svalue *. Provide no-op default implementation.
(sm_context::get_state): Add overload taking const svalue *sval.
(sm_context::set_next_state): Likewise.
(sm_context::on_transition): Likewise.
(sm_context::get_diagnostic_tree): Likewise.
* svalue.cc (svalue::all_zeroes_p): New.
(constant_svalue::all_zeroes_p): New.
(repeated_svalue::all_zeroes_p): Convert to vfunc.
* svalue.h (svalue::all_zeroes_p): New decl.
(constant_svalue::all_zeroes_p): New decl.
(repeated_svalue::all_zeroes_p): Convert decl to vfunc.
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/pattern-test-2.c: Update expected results.
* gcc.dg/plugin/analyzer_gil_plugin.c
(gil_state_machine::on_condition): Remove.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
I rewrote the way the analyzer's region_model tracks the state of memory
in GCC 11 (in 808f4dfeb3a95f50f15e71148e5c1067f90a126d), which
introduced a store with a binding_map class, mapping binding keys to
symbolic values.
The GCC 11 implementation of binding keys has an enum binding_kind,
which can be "default" vs "direct"; the idea being that direct
bindings take priority over default bindings, where the latter could
be used to represent e.g. a zero-fill of a buffer, and the former
expresses those subregions that have since been touched.
This doesn't work well: it doesn't express the idea of filling
different subregions with different values, or a memset that only
touches part of a buffer, leading to numerous XFAILs in the memset
test cases (and elsewhere).
As preparatory work towards tracking uninitialized values, this patch
eliminates the enum binding_kind, so that all bindings have
equal weight; the order in which they happen is all that matters.
If a write happens which partially overwrites an existing binding,
the new code can partially overwrite a binding, potentially punching a
hole so that an existing binding is split into two parts.
The patch adds some new classes:
- a new "bits_within_svalue" symbolic value to support extracting
parts of an existing value when its binding is partially clobbered
- a new "repeated_svalue" symbolic value to better express filling
a region with repeated copies of a symbolic value (e.g. constant
zero)
- a new "sized_region" region to express accessing a subregion
with a symbolic size in bytes
and it rewrites e.g. how memset is implemented, so that we can precisely
track which bits in a region have not been touched.
That said, the patch doesn't actually implement "uninitialized" values;
I'm saving that for a followup.
gcc/analyzer/ChangeLog:
PR analyzer/95006
* analyzer.h (class repeated_svalue): New forward decl.
(class bits_within_svalue): New forward decl.
(class sized_region): New forward decl.
(get_field_at_bit_offset): New forward decl.
* engine.cc (exploded_graph::get_or_create_node): Validate the
merged state.
(exploded_graph::maybe_process_run_of_before_supernode_enodes):
Validate the states at each stage.
* program-state.cc (program_state::validate): Validate
m_region_model.
* region-model-impl-calls.cc (region_model::impl_call_memset):
Replace special-case logic for handling constant sizes with
a call to fill_region of a sized_region with the given fill value.
* region-model-manager.cc (maybe_undo_optimize_bit_field_compare):
Drop DK_direct.
(region_model_manager::maybe_fold_sub_svalue): Fold element-based
subregions of an initial value into initial values of an element.
Fold subvalues of repeated svalues.
(region_model_manager::maybe_fold_repeated_svalue): New.
(region_model_manager::get_or_create_repeated_svalue): New.
(get_bit_range_for_field): New.
(get_byte_range_for_field): New.
(get_field_at_byte_range): New.
(region_model_manager::maybe_fold_bits_within_svalue): New.
(region_model_manager::get_or_create_bits_within): New.
(region_model_manager::get_sized_region): New.
(region_model_manager::log_stats): Update for addition of
m_repeated_values_map, m_bits_within_values_map, and
m_sized_regions.
* region-model.cc (region_model::validate): New.
(region_model::on_assignment): Drop enum binding_kind.
(region_model::get_initial_value_for_global): Likewise.
(region_model::get_rvalue_for_bits): Replace body with call to
get_or_create_bits_within.
(region_model::get_capacity): Handle RK_SIZED.
(region_model::set_value): Drop enum binding_kind.
(region_model::fill_region): New.
(region_model::get_representative_path_var_1): Handle RK_SIZED.
* region-model.h (visitor::visit_repeated_svalue): New.
(visitor::visit_bits_within_svalue): New.
(region_model_manager::get_or_create_repeated_svalue): New decl.
(region_model_manager::get_or_create_bits_within): New decl.
(region_model_manager::get_sized_region): New decl.
(region_model_manager::maybe_fold_repeated_svalue): New decl.
(region_model_manager::maybe_fold_bits_within_svalue): New decl.
(region_model_manager::repeated_values_map_t): New typedef.
(region_model_manager::m_repeated_values_map): New field.
(region_model_manager::bits_within_values_map_t): New typedef.
(region_model_manager::m_bits_within_values_map): New field.
(region_model_manager::m_sized_regions): New field.
(region_model::fill_region): New decl.
* region.cc (region::get_base_region): Handle RK_SIZED.
(region::base_region_p): Likewise.
(region::get_byte_size_sval): New.
(get_field_at_bit_offset): Make non-static.
(region::calc_offset): Move implementation of cases to
get_relative_concrete_offset vfunc implementations. Handle
RK_SIZED.
(region::get_relative_concrete_offset): New.
(decl_region::get_svalue_for_initializer): Drop enum binding_kind.
(field_region::get_relative_concrete_offset): New, from
region::calc_offset.
(element_region::get_relative_concrete_offset): Likewise.
(offset_region::get_relative_concrete_offset): Likewise.
(sized_region::accept): New.
(sized_region::dump_to_pp): New.
(sized_region::get_byte_size): New.
(sized_region::get_bit_size): New.
* region.h (enum region_kind): Add RK_SIZED.
(region::dyn_cast_sized_region): New.
(region::get_byte_size): Make virtual.
(region::get_bit_size): Likewise.
(region::get_byte_size_sval): New decl.
(region::get_relative_concrete_offset): New decl.
(field_region::get_relative_concrete_offset): New decl.
(element_region::get_relative_concrete_offset): Likewise.
(offset_region::get_relative_concrete_offset): Likewise.
(class sized_region): New.
* store.cc (binding_kind_to_string): Delete.
(binding_key::make): Drop enum binding_kind.
(binding_key::dump_to_pp): Delete.
(binding_key::cmp_ptrs): Drop enum binding_kind.
(bit_range::contains_p): New.
(byte_range::dump): New.
(byte_range::contains_p): New.
(byte_range::cmp): New.
(concrete_binding::dump_to_pp): Drop enum binding_kind.
(concrete_binding::cmp_ptr_ptr): Likewise.
(symbolic_binding::dump_to_pp): Likewise.
(symbolic_binding::cmp_ptr_ptr): Likewise.
(binding_map::apply_ctor_val_to_range): Likewise.
(binding_map::apply_ctor_pair_to_child_region): Likewise.
(binding_map::get_overlapping_bindings): New.
(binding_map::remove_overlapping_bindings): New.
(binding_cluster::validate): New.
(binding_cluster::bind): Drop enum binding_kind.
(binding_cluster::bind_compound_sval): Likewise.
(binding_cluster::purge_region): Likewise.
(binding_cluster::zero_fill_region): Reimplement in terms of...
(binding_cluster::fill_region): New.
(binding_cluster::mark_region_as_unknown): Drop enum binding_kind.
(binding_cluster::get_binding): Likewise.
(binding_cluster::get_binding_recursive): Likewise.
(binding_cluster::get_any_binding): Likewise.
(binding_cluster::maybe_get_compound_binding): Reimplement.
(binding_cluster::get_overlapping_bindings): Delete.
(binding_cluster::remove_overlapping_bindings): Reimplement in
terms of binding_map::remove_overlapping_bindings.
(binding_cluster::can_merge_p): Update for removal of
enum binding_kind.
(binding_cluster::on_unknown_fncall): Drop enum binding_kind.
(binding_cluster::maybe_get_simple_value): Likewise.
(store_manager::get_concrete_binding): Likewise.
(store_manager::get_symbolic_binding): Likewise.
(store::validate): New.
(store::set_value): Drop enum binding_kind.
(store::zero_fill_region): Reimplement in terms of...
(store::fill_region): New.
(selftest::test_binding_key_overlap): Drop enum binding_kind.
* store.h (enum binding_kind): Delete.
(binding_kind_to_string): Delete decl.
(binding_key::make): Drop enum binding_kind.
(binding_key::dump_to_pp): Make pure virtual.
(binding_key::get_kind): Delete.
(binding_key::mark_deleted): Delete.
(binding_key::mark_empty): Delete.
(binding_key::is_deleted): Delete.
(binding_key::is_empty): Delete.
(binding_key::binding_key): Delete.
(binding_key::impl_hash): Delete.
(binding_key::impl_eq): Delete.
(binding_key::m_kind): Delete.
(bit_range::get_last_bit_offset): New.
(bit_range::contains_p): New.
(byte_range::contains_p): New.
(byte_range::operator==): New.
(byte_range::get_start_byte_offset): New.
(byte_range::get_next_byte_offset): New.
(byte_range::get_last_byte_offset): New.
(byte_range::as_bit_range): New.
(byte_range::cmp): New.
(concrete_binding::concrete_binding): Drop enum binding_kind.
(concrete_binding::hash): Likewise.
(concrete_binding::operator==): Likewise.
(concrete_binding::mark_deleted): New.
(concrete_binding::mark_empty): New.
(concrete_binding::is_deleted): New.
(concrete_binding::is_empty): New.
(default_hash_traits<ana::concrete_binding>::empty_zero_p): Make false.
(symbolic_binding::symbolic_binding): Drop enum binding_kind.
(symbolic_binding::hash): Likewise.
(symbolic_binding::operator==): Likewise.
(symbolic_binding::mark_deleted): New.
(symbolic_binding::mark_empty): New.
(symbolic_binding::is_deleted): New.
(symbolic_binding::is_empty): New.
(binding_map::remove_overlapping_bindings): New decl.
(binding_map::get_overlapping_bindings): New decl.
(binding_cluster::validate): New decl.
(binding_cluster::bind): Drop enum binding_kind.
(binding_cluster::fill_region): New decl.
(binding_cluster::get_binding): Drop enum binding_kind.
(binding_cluster::get_binding_recursive): Likewise.
(binding_cluster::get_overlapping_bindings): Delete.
(store::validate): New decl.
(store::set_value): Drop enum binding_kind.
(store::fill_region): New decl.
(store_manager::get_concrete_binding): Drop enum binding_kind.
(store_manager::get_symbolic_binding): Likewise.
* svalue.cc (svalue::cmp_ptr): Handle SK_REPEATED and
SK_BITS_WITHIN.
(svalue::extract_bit_range): New.
(svalue::maybe_fold_bits_within): New.
(constant_svalue::maybe_fold_bits_within): New.
(unknown_svalue::maybe_fold_bits_within): New.
(unaryop_svalue::maybe_fold_bits_within): New.
(repeated_svalue::repeated_svalue): New.
(repeated_svalue::dump_to_pp): New.
(repeated_svalue::accept): New.
(repeated_svalue::all_zeroes_p): New.
(repeated_svalue::maybe_fold_bits_within): New.
(bits_within_svalue::bits_within_svalue): New.
(bits_within_svalue::dump_to_pp): New.
(bits_within_svalue::maybe_fold_bits_within): New.
(bits_within_svalue::accept): New.
(bits_within_svalue::implicitly_live_p): New.
(compound_svalue::maybe_fold_bits_within): New.
* svalue.h (enum svalue_kind): Add SK_REPEATED and SK_BITS_WITHIN.
(svalue::dyn_cast_repeated_svalue): New.
(svalue::dyn_cast_bits_within_svalue): New.
(svalue::extract_bit_range): New decl.
(svalue::maybe_fold_bits_within): New vfunc decl.
(region_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
(region_svalue::key_t::is_empty): Likewise.
(default_hash_traits<region_svalue::key_t>::empty_zero_p): Make false.
(constant_svalue::maybe_fold_bits_within): New.
(unknown_svalue::maybe_fold_bits_within): New.
(poisoned_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
(poisoned_svalue::key_t::is_empty): Likewise.
(default_hash_traits<poisoned_svalue::key_t>::empty_zero_p): Make
false.
(setjmp_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
(setjmp_svalue::key_t::is_empty): Likewise.
(default_hash_traits<setjmp_svalue::key_t>::empty_zero_p): Make
false.
(unaryop_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
(unaryop_svalue::key_t::is_empty): Likewise.
(unaryop_svalue::maybe_fold_bits_within): New.
(default_hash_traits<unaryop_svalue::key_t>::empty_zero_p): Make
false.
(binop_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
(binop_svalue::key_t::is_empty): Likewise.
(default_hash_traits<binop_svalue::key_t>::empty_zero_p): Make
false.
(sub_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
(sub_svalue::key_t::is_empty): Likewise.
(default_hash_traits<sub_svalue::key_t>::empty_zero_p): Make
false.
(class repeated_svalue): New.
(is_a_helper <const repeated_svalue *>::test): New.
(struct default_hash_traits<repeated_svalue::key_t>): New.
(class bits_within_svalue): New.
(is_a_helper <const bits_within_svalue *>::test): New.
(struct default_hash_traits<bits_within_svalue::key_t>): New.
(widening_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
(widening_svalue::key_t::is_empty): Likewise.
(default_hash_traits<widening_svalue::key_t>::empty_zero_p): Make
false.
(compound_svalue::key_t::mark_empty): Use 2 rather than NULL_TREE.
(compound_svalue::key_t::is_empty): Likewise.
(compound_svalue::maybe_fold_bits_within): New.
(default_hash_traits<compound_svalue::key_t>::empty_zero_p): Make
false.
gcc/testsuite/ChangeLog:
PR analyzer/95006
* gcc.dg/analyzer/clobbers-1.c: New test.
* gcc.dg/analyzer/clobbers-2.c: New test.
* gcc.dg/analyzer/data-model-1.c (test_26): Mark xfail as fixed.
(test_28): Likewise.
(test_52): Likewise. Add coverage for end of buffer.
* gcc.dg/analyzer/explode-1.c: Add leak warning.
* gcc.dg/analyzer/memset-1.c (test_3): Mark xfail as fixed.
(test_4): Use char. Mark xfail as fixed.
(test_6b): New.
(test_7): Mark xfail as fixed. Add coverage for start of buffer.
(test_8): New.
(test_9): New.
* gcc.dg/analyzer/memset-CVE-2017-18549-1.c: New test.
* gcc.dg/analyzer/symbolic-8.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
Delete an overzealous copy&paste.
gcc/analyzer/ChangeLog:
* svalue.h (conjured_svalue::iterator_t): Delete.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
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.
|
|
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.
|
|
gcc/analyzer/ChangeLog:
PR analyzer/97074
* store.cc (binding_cluster::can_merge_p): Add "out_store" param
and pass to calls to binding_cluster::make_unknown_relative_to.
(binding_cluster::make_unknown_relative_to): Add "out_store"
param. Use it to mark base regions that are pointed to by
pointers that become unknown as having escaped.
(store::can_merge_p): Pass out_store to
binding_cluster::can_merge_p.
* store.h (binding_cluster::can_merge_p): Add "out_store" param.
(binding_cluster::make_unknown_relative_to): Likewise.
* svalue.cc (region_svalue::implicitly_live_p): New vfunc.
* svalue.h (region_svalue::implicitly_live_p): New vfunc decl.
gcc/testsuite/ChangeLog:
PR analyzer/97074
* gcc.dg/analyzer/pr97074.c: New test.
|
|
|
|
gcc/ChangeLog:
* Makefile.in (ANALYZER_OBJS): Add analyzer/complexity.o.
gcc/analyzer/ChangeLog:
* analyzer.h (class state_machine): New forward decl.
(class logger): Likewise.
(class visitor): Likewise.
* complexity.cc: New file, taken from svalue.cc.
* complexity.h: New file, taken from region-model.h.
* region-model.h: Include "analyzer/svalue.h" and
"analyzer/region.h". Move struct complexity to complexity.h.
Move svalue, its subclasses and supporting decls to svalue.h.
Move region, its subclasses and supporting decls to region.h.
* region.cc: Include "analyzer/region.h".
(symbolic_region::symbolic_region): Move here from region-model.h.
* region.h: New file, based on material from region-model.h.
* svalue.cc: Include "analyzer/svalue.h".
(complexity::complexity): Move to complexity.cc.
(complexity::from_pair): Likewise.
* svalue.h: New file, based on material from region-model.h.
|