#3073

REQUIRE(std::indirect(42) == 42) fails to compile with gcc and clang

Openjogerhopened 8mo ago

Describe the bug Using Catch2 with REQUIRE(std::indirect(42) == 42) triggers a recursive constraint satisfaction error with gcc and clang.

error: satisfaction of atomic constraint 'requires(const _Tp& __t, const _Up& __u) {__t == __u;} [with _Tp = _Tp; _Up = _Up]' depends on itself

Expected behavior REQUIRE(std::indirect(42) == 42) should compile and pass.

Reproduction steps Build this snippet with x86-64 gcc trunk and -std=c++26

#include <catch2/catch_all.hpp>
#include <memory>

TEST_CASE( "std::indirect(42) compares equal to 42" ) {
    REQUIRE(std::indirect(42) == 42);
}

Platform information:

  • OS: Compiler Explorer
  • Compiler+version: x86-64 gcc trunk and x86-64 clang trunk
  • Catch version: Tested with trunk and 3.0.1

Activity

2
akasakariko5d ago

I'd like to work on this

akasakariko5d ago

This appears to be a libstdc++ issue already fixed by GCC commit 35d754588329660ea297bca621747840bffbc7e5 for PR libstdc++/124890

Verified with unmodified Catch2 devel at 08092139210881f01a34e60c5f2fd6afa0ea4024 in C++26 mode

  • GCC 16.2 and Clang 19.1.7 using libstdc++ 16.2 both compile and run the original example successfully, with 1 passing assertion
  • Using GCC 16.2 with the historical bits/indirect.h from GCC commit 152f4daab44d897b08cce8e259525e0a306be8dc reproduces the reported self-dependent atomic constraint error
  • Applying only the two-line upstream fix to that historical header makes the original example compile, without any Catch2 changes
  • The upstream regression example using std::vector<std::indirect<int>>::iterator also fails before and compiles after the same header fix, without including Catch2

The upstream fix makes the heterogeneous equality overload’s indirect parameter dependent so that unrelated arguments are rejected before recursively checking its constraints

No Catch2 fix PR appears necessary for this reproducer