VS2026: cl.exe 19.51+ miscompiles calls to CHECK()
Description
Since cl.exe 19.51 (latest cl release in Visual Studio 2026), some calls to doctest's CHECK() or CHECK_UNARY() in optimized builds are now miscompiling.
On the same compiler version, calling the same code in assert() or even explicit if() yields the expected results, so apparently this is triggered by doctest code under CHECK() or CHECK_UNARY(). This happens only with a particular method and a particular param value. Hundreds of thousands of other assertions from my code base succeed just as always; only this one fails.
This looks to be a regression in cl.exe 19.51; the problem does not happen with 19.44 (proof in gist linked below) or 19.50 (but no proof, as this version was lost in the update).
I think this is more a problem in Visual Studio than in doctest. I submitted a bug report for the problem in MSDN.
But I think you should be aware of the situation and maybe, if appropriate, take some steps to mitigate the situation on what is such an important compiler.
Steps to reproduce
I created a self-contained gist with the MVE, with fully-comented code and sample output. To run locally:
# run in a Git or MSYS bash shell in Windows
( set -xe ; \
git clone https://gist.github.com/biojppm/057530b910182c7933281318aa92af2e miscompile-19.51 \
&& cd miscompile-19.51 \
&& ./run.sh -G "Visual Studio 18 2026" )The code looks like this (incomplete):
struct csubstr
{
const char * str;
size_t len;
/** true if the last @p num characters of the string are equal to @p c */
bool ends_with(const char c, const size_t num) const noexcept
{
if(len < num)
return false;
for(size_t i = len - num; i < len; ++i)
if(str[i] != c)
return false;
return num > 0;
}
};
TEST_CASE("miscompiles")
{
// all these assertions must pass.
// failures occur only when the last param==1 (!)
CHECK( csubstr("1").ends_with('1', 1));
CHECK( ! csubstr("1234").ends_with('1', 1)); // FAILS
CHECK( csubstr("1234").ends_with('4', 1)); // FAILS
CHECK( csubstr("12345").ends_with('5', 1)); // FAILS
CHECK( ! csubstr("12345").ends_with('1', 1)); // FAILS
CHECK( csubstr("123455").ends_with('5', 1)); // FAILS
CHECK( ! csubstr("123455").ends_with('1', 1)); // FAILS
CHECK( csubstr("1234555").ends_with('5', 1)); // FAILS
CHECK( csubstr("12345555").ends_with('5', 1)); // FAILS
}doctest version
2.5.2
Operating system
Windows
Architecture
x64
Compiler
Visual Studio 2026 , cl.exe 19.51+
Context
No response
Source: doctest/doctest