https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125590
Bug ID: 125590
Summary: contract in constexpr erroneously not constant
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: ivan.lazaric.gcc at gmail dot com
Target Milestone: ---
```cpp
using It = const char*;
struct PC {
It begin_it;
constexpr PC(It it) : begin_it(it) {}
constexpr void advance_to(It it) { begin_it = it; }
constexpr It begin() const { return begin_it; }
};
consteval {
PC pc("{}");
pc.advance_to(pc.begin() + 1);
contract_assert(pc.begin() == pc.begin());
}
```
Compiler flags: "-std=c++26 -fcontracts"
Diagnostic:
```
test_fmt.cpp:63:3: error: contract condition is not constant
63 | contract_assert(pc.begin() == pc.begin());
| ^~~~~~~~~~~~~~~
PROGRAM FAILED WITH EXIT CODE 1
```
Godbolt: https://godbolt.org/z/GfTvn9bo5
The condition in `contract_assert()` should be vacuously true,
replacing the statement with `if (!(cond)) throw;` passes
This is minimized from trying to use contracts in std::format related code
```cpp
#include <format>
struct S {};
template<>
struct std::formatter<S, char> {
constexpr auto parse(auto& ctx) {
contract_assert(ctx.begin() == ctx.begin());
return ctx.begin();
}
auto format(S, auto& ctx) { return ctx.out(); }
};
consteval {
std::format_string<S> fmt("{}");
}
```
Godbolt: https://godbolt.org/z/1njKeE1sK