From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 4B8043858C56; Mon, 16 May 2022 19:35:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4B8043858C56 From: "cvs-commit at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug analyzer/105103] RFE: detect bogus use of varargs in analyzer Date: Mon, 16 May 2022 19:35:08 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: analyzer X-Bugzilla-Version: 12.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: cvs-commit at gcc dot gnu.org X-Bugzilla-Status: ASSIGNED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: dmalcolm at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 May 2022 19:35:08 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D105103 --- Comment #2 from CVS Commits --- The master branch has been updated by David Malcolm : https://gcc.gnu.org/g:2402dc6b982c4dacac2360830f0edc123c588110 commit r13-514-g2402dc6b982c4dacac2360830f0edc123c588110 Author: David Malcolm Date: Mon May 16 15:32:11 2022 -0400 analyzer: implement four new warnings for misuses [PR105103] This patch adds support to the analyzer for checking usage of , 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 =3D 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 =3D va_arg (ap, const char *); | | ~ | | | | | (4) 'va_arg' expected 'const char *' but rece= ived '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 vfun= c. * 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): Dr= op 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_AR= G, 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_AR= G. (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 ::test): New. (struct default_hash_traits): 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 =