Go to file
Iain Sandoe d1706235ed 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 <iain@sandoe.co.uk>
2024-07-16 16:58:52 +01:00
.github
c++tools
config
contrib Daily bump. 2024-07-14 00:16:33 +00:00
fixincludes Daily bump. 2024-07-12 00:17:52 +00:00
gcc c++, coroutines, contracts: Handle coroutine and void functions [PR110871,PR110872,PR115434]. 2024-07-16 16:58:52 +01:00
gnattools
gotools
include
INSTALL
libada
libatomic
libbacktrace libbacktrace: support FDPIC 2024-07-15 17:28:28 -07:00
libcc1
libcody
libcpp Daily bump. 2024-07-14 00:16:33 +00:00
libdecnumber
libffi
libgcc
libgfortran Daily bump. 2024-07-12 00:17:52 +00:00
libgm2
libgo
libgomp
libgrust
libiberty libiberty/buildargv: handle input consisting of only white space 2024-07-16 13:52:03 +01:00
libitm
libobjc
libphobos
libquadmath
libsanitizer
libssp
libstdc++-v3 Daily bump. 2024-07-13 00:17:42 +00:00
libvtv
lto-plugin
maintainer-scripts
zlib
.dir-locals.el
.gitattributes
.gitignore
ABOUT-NLS
ar-lib
ChangeLog Daily bump. 2024-07-14 00:16:33 +00:00
ChangeLog.jit
ChangeLog.tree-ssa
compile
config-ml.in
config.guess
config.rpath
config.sub
configure
configure.ac
COPYING
COPYING3
COPYING3.LIB
COPYING.LIB
COPYING.RUNTIME
depcomp
install-sh
libtool-ldflags
libtool.m4
lt~obsolete.m4
ltgcc.m4
ltmain.sh
ltoptions.m4
ltsugar.m4
ltversion.m4
MAINTAINERS Add gcc.gnu.org account names to MAINTAINERS 2024-07-13 16:22:58 +01:00
Makefile.def
Makefile.in
Makefile.tpl
missing
mkdep
mkinstalldirs
move-if-change
multilib.am
README
SECURITY.txt
symlink-tree
test-driver
ylwrap

This directory contains the GNU Compiler Collection (GCC).

The GNU Compiler Collection is free software.  See the files whose
names start with COPYING for copying permission.  The manuals, and
some of the runtime libraries, are under different terms; see the
individual source files for details.

The directory INSTALL contains copies of the installation information
as HTML and plain text.  The source of this information is
gcc/doc/install.texi.  The installation information includes details
of what is included in the GCC sources and what files GCC installs.

See the file gcc/doc/gcc.texi (together with other files that it
includes) for usage and porting information.  An online readable
version of the manual is in the files gcc/doc/gcc.info*.

See http://gcc.gnu.org/bugs/ for how to report bugs usefully.

Copyright years on GCC source files may be listed using range
notation, e.g., 1987-2012, indicating that every year in the range,
inclusive, is a copyrightable year that could otherwise be listed
individually.