Skip to content

Conversation

@iains
Copy link

@iains iains commented Oct 26, 2025

...

villevoutilainen and others added 30 commits October 26, 2025 14:12
At present, for pre-conditions and for post-conditions with a void
return, we are not emitting a return statement. This patch adds the
relevant return statements.

gcc/cp/ChangeLog:

	* contracts.cc (finish_function_contracts): Add return
	statements to pre-condition and void post-cndition
	checking functions.

Signed-off-by: Iain Sandoe <[email protected]>
Since we now have only void functions for pre and post checks, we can simplify
the code that syntesizes the function decls.
P2680 shows a situation where optimization of contracts expressions that
exploit assumption that UB cannot occur - by completely eliding checks in
those cases; which actually prevents the contract checking to work as the
user intended.

As a proof-of-principle, this patch allows use to disable optimization of
the contract checks.  It is not proposed as a production solution - really
we need to figure out the proper course of action.
… in the correct place in the grammar. Attributes on contracts not implemented yet.
…_chainon handles error_mark_nodes properly)

- disabled inheriting contracts from base classes on virtual functions
- removed allowing contracts to appear on non first declarations
- removed check in for fcontracts-nonattr as it doesn't seem needed, but introduces an issue in
diagnosing misapplied contracts
- renamed the 'new' test suite to P2900
'build_over_call' can return a TARGET_EXPR which the contracts wrapper
machinery is not expecting.

1. move the wrapper insertion into build_cxx_call, so that we can do it
before the TARGET_EXPRs are generated (which is easier than doing surgery
on the generated ones).

2. Do not copy the original fn RESULT_DECL, but instead create a new one
that has the correct type for the wrapper return (I am not sure, but
suspect that the original fn return type can have been altered by copy
elision).

3. The hack is this:
 - in build_cxx_call, we check the fndecl to see how to handle it.
 - this is done using 'get_callee_fndecl()' which does not understand
   how to look through virtual calls.. and therefore returns NULL_TREE
   which means we then fail to add the wrapper.
 - probably, the Right Fix is to make a cp_get_callee_fndecl() that does
   understand how to look through virtual calls..
 - but, instead since there is provision to pass in an 'orig_fndecl' and
   we actually know that in build_over_call, I added some logic to do
   that.

I added contract test case for the object return and a trivial coroutines
one.

Not sure whether any of this is working properly with optimsation enabled
(possibly because of the known D_A_O issue)

Signed-off-by: Iain Sandoe <[email protected]>
not generating duplicate definitions of pre and post check
fixing early mangling for checked function
fixing the context of postcondition identifier of a wrapper function
For a non-template member function of a class template, the PARM_DECL
is't TREE_READONLY, but the type of the parameter is const. Add
handling for that case.
NinaRanns and others added 30 commits October 26, 2025 14:12
We have altered the ordering of some of the code-gen and now it is
possible to encounter ignored and quick_enforce cases in
get_contract_semantic().

Signed-off-by: Iain Sandoe <[email protected]>
We wee looking up __cxa_current_exception_object in the global namespace
but the function (even tho it's extern "C") lives in __cxxabi.

Signed-off-by: Iain Sandoe <[email protected]>
Start work on de-attribution of P2900 contracts; make it explicit
when we are using attributes.

Signed-off-by: Iain Sandoe <[email protected]>
More renaming to be explicit about attributes, make the arguments to
the contract matcher contracts rather than attributes containing
contracts.

Signed-off-by: Iain Sandoe <[email protected]>
Some general tidies, move the use of attributes one step up the call
stack in the parser.

Signed-off-by: Iain Sandoe <[email protected]>
They are not attributes, and treating them as such is hindering progress.

In the revised design, they are kept as on-the-side data for function
decls that have contract specifiers (in a similar way to other out-of-
band specifiers).

Since we are currently still supporting attribute-based contracts for
the cxx2a case, and there is some share code, in the first instance we
have a number of cases wherewe have to select the source of the data
depending on flag_contracts_nonattr.  Eventually, these cases will be
removed (1) because we want to do the non-attribute work a different
way and (2) because we will remove the support for the attribute case
which was not adopted in the WD.

Signed-off-by: Iain Sandoe <[email protected]>
We have, at present, a mixture of pieces of declatations in cp-tree.h
and contracts.h (which is also included in cp-tree.h).  Remove all the
contracts information from cp-tree.h and re-organise it in contracts.h.

Then include contracts.h where it is needed only.

In a similar manner we have two implementations in contracts.cc where
one of them (cxx2a contracts) is intended to be deprecated and finally
removed.  However there is currently shared support code and common
public APIs.  This reorganises the code with the following head comment.

"
To facilitate maintenance, please keep the general ordering of content:

 shared local support functions
  cxx2a implementation:
    local support functions
    cxx2a-only public API
  cxx26 implementation:
    local support functions
    cxx26-only public API
 shared public API.
"

In the process, we identified some APIs that are actually local to
contracts.cc and these have been made static functions and removed
from the public API.

Signed-off-by: Iain Sandoe <[email protected]>
This replaces any uses of the to-be-deprecated attribute format options
and instead uses the current C++26 versions.  Small tidy-ups in unused
options and duplicated std specs.

Signed-off-by: Iain Sandoe <[email protected]>
When we have a specialisation, it might be given contract specifiers
(depending on whether they are present on the template, as a side-effect
of the instantiation process).  However, these added specifiers are then
deleted - since the presence of (and spelling of) specifiers on
specialisations is independent of the original template.

We were doing this by adding empty contracts to the specialisation.
This has an unfortunate side-effect of adding decls to the specifier
lookup map, even if the decl had no contracts already.  This can play
badly with GC and hash collisions.

Solve this by adding an interface that only deletes specifiers on
functions already registered.

This is subtely different from the case when we are about to
ggc_delete a decl (in that case we actually also want to remove the
decl from the map too).  So renamed that interface to say that it
will remove the decl.

Signed-off-by: Iain Sandoe <[email protected]>
We still have the option to outline them with -fcontract-checks-outlined.

Switch the tests that were checking -fno-contract-checks-outlined to do the
opposite.

Signed-off-by: Iain Sandoe <[email protected]>
This does all the work needed to have the builtin type but does not
(yet) publish it - since we are still figuring out the details of
the ABI - however,

In this version, we no longer try to declare or build a
std::source_location since this creates quite some difficulty with
needing the declaration whether <source_location> is included or not.

Instead, we save a type-erased pointer to the implementation data.
Since clang and GCC actually use the same layout here, there is a move
to add this to the Itanium spec at that point we will be able to use
some __cxa_xxxxx_t * as the pointer type.

Signed-off-by: Iain Sandoe <[email protected]>
This allows us to put values for semantic and assertion type that will
not fit into the LANG_ bits

This is intended to allow the library to make use of compiler-side logic
to implement changes in semantic handling, rather than duplicating this.
Since we want to accommodate semantics with a larger range of values
than can be fitted into the TREE_LANG_xxx bits, we have made a slot
in the contract expression tree to hold the semantic.

This switches the P2900-based implementation to use that.

Signed-off-by: Iain Sandoe <[email protected]>
Now we can accommodate values in the recommended practice range proposed
by the WD, switch the noexcept_xxx semantics to use them.

Signed-off-by: Iain Sandoe <[email protected]>
We want to allow contract checks in constructors and dsestructors
to have controlled optimisations; one way to achieve this is to
outline the checks and apply the constraints there.  This was
already possible for other functions.

Co-authored-by: Nina Ranns <[email protected]>
Signed-off-by: Iain Sandoe <[email protected]>
…dentifiers

We had a situation in which post condition function names were being
mangled with inclusion of the added return value parameter, this made
it possible that we could get a duplicate function name if there was
a void overload with an extra parm.

Co-authored-by: Iain Sandoe <[email protected]>
Signed-off-by: Iain Sandoe <[email protected]>
This alters the logic slightly in the violation_handler wrapper
so that we only generate one call to terminate.

Signed-off-by: Iain Sandoe <[email protected]>
This implements a wrapper around calls to std::terminate that are
made for enforce and quick_enforce semantics.  This works around
GCC Bugzilla 121936 while a suitable fix is found for the upstream
implementation.

Co-authored-by: Iain Sandoe <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants