public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "cvs-commit at gcc dot gnu.org" <gcc-bugzilla@gcc.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	[thread overview]
Message-ID: <bug-105103-4-1hOoPxaJsw@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-105103-4@http.gcc.gnu.org/bugzilla/>

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105103

--- Comment #2 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by David Malcolm <dmalcolm@gcc.gnu.org>:

https://gcc.gnu.org/g:2402dc6b982c4dacac2360830f0edc123c588110

commit r13-514-g2402dc6b982c4dacac2360830f0edc123c588110
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Mon May 16 15:32:11 2022 -0400

    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>

  parent reply	other threads:[~2022-05-16 19:35 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-29 20:17 [Bug analyzer/105103] New: " dmalcolm at gcc dot gnu.org
2022-04-11 14:21 ` [Bug analyzer/105103] " dmalcolm at gcc dot gnu.org
2022-05-16 19:35 ` cvs-commit at gcc dot gnu.org [this message]
2022-05-16 19:43 ` dmalcolm at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-105103-4-1hOoPxaJsw@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).