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
  • [Bug c++/125590] New: contr... ivan.lazaric.gcc at gmail dot com via Gcc-bugs

Reply via email to