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

--- Comment #16 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Benjamin Priour <vultk...@gcc.gnu.org>:

https://gcc.gnu.org/g:e7b267444045c507654a2a3f758efee5d5b550df

commit r14-3632-ge7b267444045c507654a2a3f758efee5d5b550df
Author: benjamin priour <priour...@gmail.com>
Date:   Fri Sep 1 00:01:29 2023 +0200

    analyzer: Add support of placement new and improved operator new
[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 <vultk...@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.

Reply via email to