c++/contracts: assertion predicate re-invoking constexpr function [PR125459]

The RESULT_DECL of a function during constant evaluation has its value
stored in the constexpr_global_ctx, and once its lifetime ends
void_list_node is put in its place.  If the same function is then called
later during the same constant evaluation from within the scope of a
modifiable_tracker (i.e., during speculative evaluation of a contract
assertion, or evaluation of the predicate of an [[assume]]) the population
of the return value will find an entry (void_list_node) already in the
context and treat the call as an attempt to modify outside state, resulting
in errors.

This change updates the put_value member of constexpr_global_ctx to
recognize void_list_node values in the map as not being a concern for what
modifiable is tracking, and treats them the same way it treats not yet
having a value in the map for that key.  void_node is not treated the same
way because that would indicate an object that has been destroyed but whose
storage has not yet been deallocated.

PR c++/125459 - [contracts] "contract condition is not constant" in
constexpr function

	PR c++/125459

gcc/cp/ChangeLog:

	* constexpr.cc (constexpr_global_ctx::put_value): Treat
	void_list_node as not having been in the map for modifiable
	tracking.

gcc/testsuite/ChangeLog:

	* g++.dg/contracts/cpp26/pr125459.C: New test.

Signed-off-by: Joshua Berne <berne@notadragon.com>
2 files changed