aboutsummaryrefslogtreecommitdiff
path: root/gcc/doc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2022-05-16 15:32:11 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2022-05-16 15:34:09 -0400
commit2402dc6b982c4dacac2360830f0edc123c588110 (patch)
tree95f38ecf7b3a91c1c413e2b782f1a54eb3b4b894 /gcc/doc
parent5eb9927aae076200bb7ba3f22c33b0a7c97c5643 (diff)
downloadgcc-2402dc6b982c4dacac2360830f0edc123c588110.zip
gcc-2402dc6b982c4dacac2360830f0edc123c588110.tar.gz
gcc-2402dc6b982c4dacac2360830f0edc123c588110.tar.bz2
analyzer: implement four new warnings for <stdarg.h> misuses [PR105103]
This patch adds support to the analyzer for checking usage of <stdarg.h>, with four new warnings. It adds: (a) a state-machine for tracking "started" and "ended" states on va_list instances, implementing two new warnings: -Wanalyzer-va-list-leak for complaining about missing va_end after a va_start or va_copy -Wanalyzer-va-list-use-after-va-end: for complaining about va_arg or va_copy used on a va_list that's had va_end called on it (b) interprocedural tracking of variadic parameters, tracking symbolic values, implementing two new warnings: -Wanalyzer-va-arg-type-mismatch for type-checking va_arg usage against the types of the parameters that were actually passed to the variadic call -Wanalyzer-va-list-exhausted for complaining if va_arg is used too many times on a va_list Here's an LTO example of a type mismatch in a variadic call that straddles two source files: stdarg-lto-1-a.c: In function 'called_by_test_type_mismatch_1': stdarg-lto-1-a.c:19:7: warning: 'va_arg' expected 'const char *' but received 'int' for variadic argument 1 of 'ap' [-Wanalyzer-va-arg-type-mismatch] 19 | str = va_arg (ap, const char *); | ^ 'test_type_mismatch_1': events 1-2 | |stdarg-lto-1-b.c:3:6: | 3 | void test_type_mismatch_1 (void) | | ^ | | | | | (1) entry to 'test_type_mismatch_1' | 4 | { | 5 | called_by_test_type_mismatch_1 (42, 1066); | | ~ | | | | | (2) calling 'called_by_test_type_mismatch_1' from 'test_type_mismatch_1' with 1 variadic argument | +--> 'called_by_test_type_mismatch_1': events 3-4 | |stdarg-lto-1-a.c:12:1: | 12 | called_by_test_type_mismatch_1 (int placeholder, ...) | | ^ | | | | | (3) entry to 'called_by_test_type_mismatch_1' |...... | 19 | str = va_arg (ap, const char *); | | ~ | | | | | (4) 'va_arg' expected 'const char *' but received 'int' for variadic argument 1 of 'ap' | gcc/ChangeLog: PR analyzer/105103 * Makefile.in (ANALYZER_OBJS): Add analyzer/varargs.o. * doc/invoke.texi: Add -Wanalyzer-va-arg-type-mismatch, -Wanalyzer-va-list-exhausted, -Wanalyzer-va-list-leak, and -Wanalyzer-va-list-use-after-va-end. gcc/analyzer/ChangeLog: PR analyzer/105103 * analyzer.cc (make_label_text_n): New. * analyzer.h (class var_arg_region): New forward decl. (make_label_text_n): New decl. * analyzer.opt (Wanalyzer-va-arg-type-mismatch): New option. (Wanalyzer-va-list-exhausted): New option. (Wanalyzer-va-list-leak): New option. (Wanalyzer-va-list-use-after-va-end): New option. * checker-path.cc (call_event::get_desc): Split out decl access into.. (call_event::get_caller_fndecl): ...this new function and... (call_event::get_callee_fndecl): ...this new function. * checker-path.h (call_event::get_desc): Drop "FINAL". (call_event::get_caller_fndecl): New decl. (call_event::get_callee_fndecl): New decl. (class call_event): Make fields protected. * diagnostic-manager.cc (null_assignment_sm_context::warn): New overload. (null_assignment_sm_context::get_new_program_state): New. (diagnostic_manager::add_events_for_superedge): Move case SUPEREDGE_CALL to a new pending_diagnostic::add_call_event vfunc. * engine.cc (impl_sm_context::warn): Implement new override. (impl_sm_context::get_new_program_state): New. * pending-diagnostic.cc: Include "analyzer/diagnostic-manager.h", "cpplib.h", "digraph.h", "ordered-hash-map.h", "cfg.h", "basic-block.h", "gimple.h", "gimple-iterator.h", "cgraph.h" "analyzer/supergraph.h", "analyzer/program-state.h", "alloc-pool.h", "fibonacci_heap.h", "shortest-paths.h", "sbitmap.h", "analyzer/exploded-graph.h", "diagnostic-path.h", and "analyzer/checker-path.h". (ht_ident_eq): New. (fixup_location_in_macro_p): New. (pending_diagnostic::fixup_location): New. (pending_diagnostic::add_call_event): New. * pending-diagnostic.h (pending_diagnostic::fixup_location): Drop no-op inline implementation in favor of the more complex implementation above. (pending_diagnostic::add_call_event): New vfunc. * region-model-impl-calls.cc: Include "analyzer/sm.h", "diagnostic-path.h", and "analyzer/pending-diagnostic.h". * region-model-manager.cc (region_model_manager::get_var_arg_region): New. (region_model_manager::log_stats): Log m_var_arg_regions. * region-model.cc (region_model::on_call_pre): Handle IFN_VA_ARG, BUILT_IN_VA_START, and BUILT_IN_VA_COPY. (region_model::on_call_post): Handle BUILT_IN_VA_END. (region_model::get_representative_path_var_1): Handle RK_VAR_ARG. (region_model::push_frame): Push variadic arguments. * region-model.h (region_model_manager::get_var_arg_region): New decl. (region_model_manager::m_var_arg_regions): New field. (region_model::impl_call_va_start): New decl. (region_model::impl_call_va_copy): New decl. (region_model::impl_call_va_arg): New decl. (region_model::impl_call_va_end): New decl. * region.cc (alloca_region::dump_to_pp): Dump the id. (var_arg_region::dump_to_pp): New. (var_arg_region::get_frame_region): New. * region.h (enum region_kind): Add RK_VAR_ARG. (region::dyn_cast_var_arg_region): New. (class var_arg_region): New. (is_a_helper <const var_arg_region *>::test): New. (struct default_hash_traits<var_arg_region::key_t>): New. * sm.cc (make_checkers): Call make_va_list_state_machine. * sm.h (sm_context::warn): New vfunc. (sm_context::get_old_svalue): Drop unused decl. (sm_context::get_new_program_state): New vfunc. (make_va_list_state_machine): New decl. * varargs.cc: New file. gcc/testsuite/ChangeLog: PR analyzer/105103 * gcc.dg/analyzer/stdarg-1.c: New test. * gcc.dg/analyzer/stdarg-2.c: New test. * gcc.dg/analyzer/stdarg-fmtstring-1.c: New test. * gcc.dg/analyzer/stdarg-lto-1-a.c: New test. * gcc.dg/analyzer/stdarg-lto-1-b.c: New test. * gcc.dg/analyzer/stdarg-lto-1.h: New test. * gcc.dg/analyzer/stdarg-sentinel-1.c: New test. * gcc.dg/analyzer/stdarg-types-1.c: New test. * gcc.dg/analyzer/stdarg-types-2.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/doc')
-rw-r--r--gcc/doc/invoke.texi55
1 files changed, 55 insertions, 0 deletions
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 7a35d96..e8e6d4e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -464,6 +464,10 @@ Objective-C and Objective-C++ Dialects}.
-Wno-analyzer-use-after-free @gol
-Wno-analyzer-use-of-pointer-in-stale-stack-frame @gol
-Wno-analyzer-use-of-uninitialized-value @gol
+-Wno-analyzer-va-arg-type-mismatch @gol
+-Wno-analyzer-va-list-exhausted @gol
+-Wno-analyzer-va-list-leak @gol
+-Wno-analyzer-va-list-use-after-va-end @gol
-Wno-analyzer-write-to-const @gol
-Wno-analyzer-write-to-string-literal @gol
}
@@ -9689,6 +9693,10 @@ Enabling this option effectively enables the following warnings:
-Wanalyzer-use-after-free @gol
-Wanalyzer-use-of-pointer-in-stale-stack-frame @gol
-Wanalyzer-use-of-uninitialized-value @gol
+-Wanalyzer-va-arg-type-mismatch @gol
+-Wanalyzer-va-list-exhausted @gol
+-Wanalyzer-va-list-leak @gol
+-Wanalyzer-va-list-use-after-va-end @gol
-Wanalyzer-write-to-const @gol
-Wanalyzer-write-to-string-literal @gol
}
@@ -9971,6 +9979,53 @@ to disable it.
This diagnostic warns for paths through the code in which a pointer
is dereferenced that points to a variable in a stale stack frame.
+@item -Wno-analyzer-va-arg-type-mismatch
+@opindex Wanalyzer-va-arg-type-mismatch
+@opindex Wno-analyzer-va-arg-type-mismatch
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-va-arg-type-mismatch}
+to disable it.
+
+This diagnostic warns for interprocedural paths through the code for which
+the analyzer detects an attempt to use @code{va_arg} to extract a value
+passed to a variadic call, but uses a type that does not match that of
+the expression passed to the call.
+
+@item -Wno-analyzer-va-list-exhausted
+@opindex Wanalyzer-va-list-exhausted
+@opindex Wno-analyzer-va-list-exhausted
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-va-list-exhausted}
+to disable it.
+
+This diagnostic warns for interprocedural paths through the code for which
+the analyzer detects an attempt to use @code{va_arg} to access the next
+value passed to a variadic call, but all of the values in the
+@code{va_list} have already been consumed.
+
+@item -Wno-analyzer-va-list-leak
+@opindex Wanalyzer-va-list-leak
+@opindex Wno-analyzer-va-list-leak
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-va-list-leak}
+to disable it.
+
+This diagnostic warns for interprocedural paths through the code for which
+the analyzer detects that @code{va_start} or @code{va_copy} has been called
+on a @code{va_list} without a corresponding call to @code{va_end}.
+
+@item -Wno-analyzer-va-list-use-after-va-end
+@opindex Wanalyzer-va-list-use-after-va-end
+@opindex Wno-analyzer-va-list-use-after-va-end
+This warning requires @option{-fanalyzer}, which enables it; use
+@option{-Wno-analyzer-va-list-use-after-va-end}
+to disable it.
+
+This diagnostic warns for interprocedural paths through the code for which
+the analyzer detects an attempt to use a @code{va_list} after
+@code{va_end} has been called on it.
+@code{va_list}.
+
@item -Wno-analyzer-write-to-const
@opindex Wanalyzer-write-to-const
@opindex Wno-analyzer-write-to-const