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

--- Comment #1 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Iain D Sandoe <ia...@gcc.gnu.org>:

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

commit r15-2074-gd1706235ed2b274a2d1fa3c3039b5874b4ae7a0e
Author: Iain Sandoe <i...@sandoe.co.uk>
Date:   Sat Jun 15 17:47:33 2024 +0100

    c++, coroutines, contracts: Handle coroutine and void functions
[PR110871,PR110872,PR115434].

    The current implementation of contracts emits the checks into function
    bodies in three places; for pre-conditions at the start of the body,
    for asserts in-line in the function body and for post-conditions as an
    addition to return statements.

    In general (at least with existing "2a" contract semantics) the in-line
    contract asserts behave as expected.

    However, the mechanism is not applicable to:

     * Handling pre conditions in coroutines since, for those, the standard
      specifies a wrapping of the original function body by functionality
      implementing initial and final suspends (along with some housekeeping
      to route exceptions).  Thus for such transformed function bodies, the
      preconditions then get actioned after the initial suspend, which does
      not behave as intended.

      * Handling post conditions in functions that do not have return
        statements (which applies to coroutines and void functions).

    In the following, we identify a potentially transformed function body
    (in the case of coroutines, this is usually called the "ramp()" function).

    The patch here re-implements the code insertion in one of the two
    following ways (code for exposition only):

      * For functions with no post-conditions we wrap the potentially
        transformed function as follows:

      {
         handle_pre_condition_checking ();
         potentially_transformed_function_body ();
      }

      This implements the intent that the preconditions are processed after
      the function parameters are initialised but before any other actions.

      * For functions with post-conditions:

      if (preconditions_exist)
        handle_pre_condition_checking ();
      try
       {
         potentially_transformed_function_body ();
       }
      finally
       {
         handle_post_condition_checking ();
       }
      else [only if the function is not marked noexcept(true) ]
       {
         ;
       }

    In this, post-conditions [that might apply to the return value etc.]
    are evaluated on every non-exceptional edge out of the function.

    At present, the model here is that exceptions thrown by the function
    propagate upwards as if there were no contracts present.  If the desired
    semantic becomes that an exception is counted as equivalent to a contract
    violation - then we can add a second handler in place of the empty
    statement.

    This patch specifically does not address changes to code-gen and constexpr
    handling that are contained in P2900.

            PR c++/115434
            PR c++/110871
            PR c++/110872

    gcc/cp/ChangeLog:

            * constexpr.cc (cxx_eval_constant_expression): Handle EH_ELSE_EXPR.
            * contracts.cc (finish_contract_attribute): Remove excess line.
            (build_contract_condition_function): Post condition handlers are
            void now.
            (emit_postconditions_cleanup): Remove.
            (emit_postconditions): New.
            (add_pre_condition_fn_call): New.
            (add_post_condition_fn_call): New.
            (apply_preconditions): New.
            (apply_postconditions): New.
            (maybe_apply_function_contracts): New.
            (apply_postcondition_to_return): Remove.
            * contracts.h (apply_postcondition_to_return): Remove.
            (maybe_apply_function_contracts): Add.
            * coroutines.cc (coro_build_actor_or_destroy_function): Do not
            copy contracts to coroutine helpers.
            * decl.cc (finish_function): Handle wrapping a possibly
            transformed function body in contract checks.
            * typeck.cc (check_return_expr): Remove handling of post
            conditions on return expressions.

    gcc/ChangeLog:

            * gimplify.cc (struct gimplify_ctx): Add a flag to show we are
            expending a handler.
            (gimplify_expr): When we are expanding a handler, and the body
            transforms might have re-written DECL_RESULT into a gimple var,
            ensure that hander references to DECL_RESULT are also re-written
            to refer to the gimple var.  When we are processing an EH_ELSE
            expression, then add it if either of the cleanup slots is in
            use.

    gcc/testsuite/ChangeLog:

            * g++.dg/contracts/pr115434.C: New test.
            * g++.dg/coroutines/pr110871.C: New test.
            * g++.dg/coroutines/pr110872.C: New test.

    Signed-off-by: Iain Sandoe <i...@sandoe.co.uk>
  • [Bug c++/110871] coroutine prec... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to