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

--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Patrick Palka <ppa...@gcc.gnu.org>:

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

commit r11-550-gf65a3299a521a44522c1e01724f75e36af22f40b
Author: Patrick Palka <ppa...@redhat.com>
Date:   Thu May 21 09:03:43 2020 -0400

    c++: template instantiation during fold_for_warn [PR94038]

    Unfortunately, the previous fix to PR94038 is fragile.  When the
    argument to fold_for_warn is a bare CALL_EXPR, then all is well: the
    result of maybe_constant_value from fold_for_warn (with
    uid_sensitive=true) is reused via the cv_cache in the subsequent call to
    maybe_constant_value from cp_fold (with uid_sensitive=false), so we
    avoid instantiating bar<int>.

    But when the argument to fold_for_warn is more complex, e.g. an
    INDIRECT_REF of a CALL_EXPR, as in the testcase below (due to bar<int>()
    returning const int& which we need to decay to int) then from
    fold_for_warn we call maybe_constant_value on the INDIRECT_REF, and from
    cp_fold we call it on the CALL_EXPR, so there is no reuse via the
    cv_cache and we therefore end up instantiating bar<int>.

    So for a more robust solution to this general issue of warning flags
    affecting code generation, it seems that we need a way to globally avoid
    template instantiation during constexpr evaluation whenever we're
    performing warning-dependent folding.

    To that end, this patch replaces the flag constexpr_ctx::uid_sensitive
    with a global flag uid_sensitive_constexpr_evaluation_p, and enables it
    during fold_for_warn using an RAII helper.

    The patch also adds a counter that keeps track of the number of times
    uid_sensitive_constexpr_evaluation_p is called and returned true, and we
    use this to determine whether the result of constexpr evaluation
    was restricted by the flag.  This lets us safely update the cv_cache and
    fold_cache from fold_for_warn in the most common case where the flag
    did not restrict constexpr evaluation.

    gcc/cp/ChangeLog:

            PR c++/94038
            * constexpr.c (constexpr_ctx::uid_sensitive): Remove field.
            (uid_sensitive_constexpr_evaluation_value): Define.
            (uid_sensitive_constexpr_evaluation_true_counter): Define.
            (uid_sensitive_constexpr_evaluation_p): Define.
            (uid_sensitive_constexpr_evaluation_sentinel): Define its
            constructor.
            (uid_sensitive_constexpr_evaluation_checker): Define its
            constructor and its evaluation_restricted_p method.
            (get_fundef_copy): Remove 'ctx' parameter.  Use u_s_c_e_p
            instead of constexpr_ctx::uid_sensitive.
            (cxx_eval_call_expression): Use u_s_c_e_p instead, and test it
            last.  Adjust call to get_fundef_copy.
            (instantiate_cx_fn_r): Test u_s_c_e_p so that we increment the
            counter if necessary.
            (cxx_eval_outermost_constant_expr): Remove 'uid_sensitive'
            parameter.  Adjust function body accordingly.
            (maybe_constant_value): Remove 'uid_sensitive' parameter and
            adjust function body accordingly.  Set up a
            uid_sensitive_constexpr_evaluation_checker, and use it to
            conditionally update the cv_cache.
            * cp-gimplify.c (cp_fold): Set up a
            uid_sensitive_constexpr_evaluation_checker, and use it to
            conditionally update the fold_cache.
            * cp-tree.h (maybe_constant_value): Update declaration.
            (struct uid_sensitive_constexpr_evaluation_sentinel): Define.
            (struct sensitive_constexpr_evaluation_checker): Define.
            * expr.c (fold_for_warn): Set up a
            uid_sensitive_constexpr_evaluation_sentinel before calling
            the folding subroutines.  Drop all but the first argument to
            maybe_constant_value.

    gcc/testsuite/ChangeLog:

            PR c++/94038
            * g++.dg/warn/pr94038-2.C: New test.

Reply via email to