Repository: bitcoin/bitcoin
File: src/test/uint256_tests.cpp (C++)

Code before:
BOOST_AUTO_TEST_CASE( operator_with_self )
{
    arith_uint256 v = UintToArith256(uint256S("02"));
    v *= v;
    BOOST_CHECK(v == UintToArith256(uint256S("04")));
    v /= v;
    BOOST_CHECK(v == UintToArith256(uint256S("01")));
    v += v;
    BOOST_CHECK(v == UintToArith256(uint256S("02")));
    v -= v;
    BOOST_CHECK(v == UintToArith256(uint256S("0")));
}

BOOST_AUTO_TEST_CASE(parse)
{
    {
        std::string s_12{"0000000000000000000000000000000000000000000000000000000000000012"};
        BOOST_CHECK_EQUAL(uint256S("12\0").GetHex(), s_12);
        BOOST_CHECK_EQUAL(uint256S(std::string{"12\0", 3}).GetHex(), s_12);
        BOOST_CHECK_EQUAL(uint256S("0x12").GetHex(), s_12);
        BOOST_CHECK_EQUAL(uint256S(" 0x12").GetHex(), s_12);
        BOOST_CHECK_EQUAL(uint256S(" 12").GetHex(), s_12);
    }
    {
        std::string s_1{uint256::ONE.GetHex()};
        BOOST_CHECK_EQUAL(uint256S("1\0").GetHex(), s_1);
        BOOST_CHECK_EQUAL(uint256S(std::string{"1\0", 2}).GetHex(), s_1);
        BOOST_CHECK_EQUAL(uint256S("0x1").GetHex(), s_1);
        BOOST_CHECK_EQUAL(uint256S(" 0x1").GetHex(), s_1);
        BOOST_CHECK_EQUAL(uint256S(" 1").GetHex(), s_1);
    }
    {
        std::string s_0{uint256::ZERO.GetHex()};
        BOOST_CHECK_EQUAL(uint256S("\0").GetHex(), s_0);
        BOOST_CHECK_EQUAL(uint256S(std::string{"\0", 1}).GetHex(), s_0);
        BOOST_CHECK_EQUAL(uint256S("0x").GetHex(), s_0);
        BOOST_CHECK_EQUAL(uint256S(" 0x").GetHex(), s_0);
        BOOST_CHECK_EQUAL(uint256S(" ").GetHex(), s_0);
    }
}

BOOST_AUTO_TEST_CASE( check_ONE )
{
    uint256 one = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
    BOOST_CHECK_EQUAL(one, uint256::ONE);
}

BOOST_AUTO_TEST_SUITE_END()


Review comment (suggestion):
```suggestion
    v -= auto(v);
```

nit: I presume, an alternative would be to create a copy (C++23), or with C++20:

```
v -= arith_uint256{v};
```

But either seems fine.

Code after:
BOOST_AUTO_TEST_CASE( operator_with_self )
{

/* Clang 16 and earlier detects v -= v and v /= v as self-assignments
   to 0 and 1 respectively.
   See: https://github.com/llvm/llvm-project/issues/42469
   and the fix in commit c5302325b2a62d77cf13dd16cd5c19141862fed0 .

   This makes some sense for arithmetic classes, but could be considered a bug
   elsewhere. Disable the warning here so that the code can be tested, but the
   warning should remain on as there will likely always be a better way to
   express this.
*/

#if defined(__clang__)
#    pragma clang diagnostic push
#    pragma clang diagnostic ignored "-Wself-assign-overloaded"
#endif
    arith_uint256 v = UintToArith256(uint256S("02"));
    v *= v;
    BOOST_CHECK(v == UintToArith256(uint256S("04")));
    v /= v;
    BOOST_CHECK(v == UintToArith256(uint256S("01")));
    v += v;
    BOOST_CHECK(v == UintToArith256(uint256S("02")));
    v -= v;
    BOOST_CHECK(v == UintToArith256(uint256S("0")));
#if defined(__clang__)
#    pragma clang diagnostic pop
#endif
}

BOOST_AUTO_TEST_CASE(parse)
{
    {
        std::string s_12{"0000000000000000000000000000000000000000000000000000000000000012"};
        BOOST_CHECK_EQUAL(uint256S("12\0").GetHex(), s_12);
        BOOST_CHECK_EQUAL(uint256S(std::string{"12\0", 3}).GetHex(), s_12);
        BOOST_CHECK_EQUAL(uint256S("0x12").GetHex(), s_12);
        BOOST_CHECK_EQUAL(uint256S(" 0x12").GetHex(), s_12);
        BOOST_CHECK_EQUAL(uint256S(" 12").GetHex(), s_12);
    }
    {
        std::string s_1{uint256::ONE.GetHex()};
        BOOST_CHECK_EQUAL(uint256S("1\0").GetHex(), s_1);
        BOOST_CHECK_EQUAL(uint256S(std::string{"1\0", 2}).GetHex(), s_1);
        BOOST_CHECK_EQUAL(uint256S("0x1").GetHex(), s_1);
        BOOST_CHECK_EQUAL(uint256S(" 0x1").GetHex(), s_1);
        BOOST_CHECK_EQUAL(uint256S(" 1").GetHex(), s_1);
    }
    {