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

--- Comment #20 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-10 branch has been updated by Jakub Jelinek
<ja...@gcc.gnu.org>:

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

commit r10-9722-ge961da38630c892dfc0723e0726b6a0b0833e951
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Apr 8 17:15:39 2021 +0200

    c++: Don't cache constexpr functions which are passed pointers to heap or
static vars being constructed [PR99859]

    When cxx_bind_parameters_in_call is called e.g. on a method on an automatic
    variable, we evaluate the argument and because ADDR_EXPR of an automatic
    decl is not TREE_CONSTANT, we set *non_constant_args and don't cache it.
    But when it is called on an object located on the heap (allocated using
    C++20 constexpr new) where we represent it as TREE_STATIC artificial
    var, or when it is called on a static var that is currently being
    constructed, such ADDR_EXPRs are TREE_CONSTANT and we happily cache
    such calls, but they can in those cases have side-effects in the heap
    or static var objects and so caching them means such side-effects will
    happen only once and not as many times as that method or function is
called.
    Furthermore, as Patrick mentioned in the PR, the argument doesn't need to
be
    just ADDR_EXPR of the heap or static var or its components, but it could be
    a CONSTRUCTOR that has the ADDR_EXPR embedded anywhere.
    And the incorrectly cached function doesn't need to modify the pointed vars
    or their components, but some caller could be changing them in between the
    call that was cached and the call that used the cached result.

    The following patch fixes it by setting *non_constant_args also when
    the argument contains somewhere such an ADDR_EXPR, either of a heap
    artificial var or component thereof, or of a static var currently being
    constructed (where for that it uses the same check as
    cxx_eval_store_expression, ctx->global->values.get (...); addresses of
    other static variables would be rejected by cxx_eval_store_expression
    and therefore it is ok to cache such calls).

    2021-04-08  Jakub Jelinek  <ja...@redhat.com>

            PR c++/99859
            * constexpr.c (addr_of_non_const_var): New function.
            (cxx_bind_parameters_in_call): Set *non_constant_args to true
            even if cp_walk_tree on arg with addr_of_non_const_var callback
            returns true.

            * g++.dg/cpp1y/constexpr-99859-1.C: New test.
            * g++.dg/cpp1y/constexpr-99859-2.C: New test.
            * g++.dg/cpp2a/constexpr-new18.C: New test.
            * g++.dg/cpp2a/constexpr-new19.C: New test.

    (cherry picked from commit 559d2f1e0eafd96c19dc5324db1a466286c0e7fc)

Reply via email to