https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124100
Bug ID: 124100
Summary: "contract condition is not constant"
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: webrown.cpp at gmail dot com
Target Milestone: ---
As demonstrated at https://godbolt.org/z/KjxET5rrP, the following code produces
the unexpected diagnostic
16:5: error: contract condition is not constant
when compiled on trunk with flags -std=c++26 -fcontracts -Wall.
The diagnostic does not manifest:
- without -Wall, or
- when *either* of the 2 lines guarded by #ifdef is absent.
```
#define BUG
using ptrdiff_t = decltype( (char *)nullptr - (char *)nullptr );
auto is_neg = [] ( ptrdiff_t k ) { return k < 0; };
auto is_pos = [] ( ptrdiff_t k ) { return k > 0; };
auto abs2 = [] ( ptrdiff_t k ) { return is_neg(k) ? -k : k; };
template< class > concept bi = true;
struct
adv final
{
template< class I >
static constexpr void
operator () ( I & i, ptrdiff_t n ) noexcept
pre( bi<I> ) // error: "contract condition is not constant"
{ for( ; is_pos(n); --n ) ++i; }
template< class I, class S >
static constexpr ptrdiff_t
operator () ( I & i, ptrdiff_t n, S bound ) noexcept
{
ptrdiff_t const delta = bound - i;
ptrdiff_t const M = abs2(n) > abs2(delta) ? delta : n;
adv{}(i, M);
return n - M;
}
}
constexpr adv{};
struct
nxt final
{
template< class I, class S >
static constexpr I
operator () ( I x, ptrdiff_t n, S bound ) noexcept
{ return (void)adv(x, n, bound), x; }
}
constexpr nxt{};
//////////////////////////////////////////////////////////////////////////////
constexpr int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
#ifdef BUG
static_assert( nxt(a+0, 3, a+9) == a+3 );
static_assert( nxt(a+0, 6, a+5) == a+5 );
#endif // BUG
constexpr bool
test( int const * lower, int n, int const * upper, int const * expected )
{ return nxt(lower, n, upper) == expected; }
static_assert( test(a+0, 3, a+9, a+3) );
static_assert( test(a+0, 6, a+5, a+5) );
```