Interesting it looks like there are only a few places according to the last ci run....
<details><summary>ai slop list of the places</summary>
All return-type warnings end with assert(false) but no explicit return; clang-cl does not treat that as terminating on every path.
1. src/script/interpreter.cpp:415 (src/script/interpreter.cpp:415) — EvalChecksig
case SigVersion::TAPROOT:
// Key path spending in Taproot has no script, so this is unreachable.
break;
}
assert(false);
}
2. src/script/interpreter.cpp:1490 (src/script/interpreter.cpp:1490) — HandleMissingData
case MissingDataBehavior::ASSERT_FAIL:
assert(!"Missing data");
break;
case MissingDataBehavior::FAIL:
return false;
}
assert(!"Unknown MissingDataBehavior value");
}
3. src/netaddress.cpp:47 (src/netaddress.cpp:47) — CNetAddr::GetBIP155Network
case NET_INTERNAL:
case NET_UNROUTABLE:
case NET_MAX:
assert(false);
}
assert(false);
}
4. src/netaddress.cpp:500 (src/netaddress.cpp:500) — CNetAddr::IsAddrV1Compatible
case NET_UNROUTABLE:
case NET_MAX:
assert(false);
}
assert(false);
}
5. src/netaddress.cpp:607 (src/netaddress.cpp:607) — CNetAddr::ToStringAddr
case NET_UNROUTABLE:
case NET_MAX:
assert(false);
}
assert(false);
}
6. src/netaddress.cpp:678 (src/netaddress.cpp:678) — CNetAddr::GetLinkedIPv4
} else if (IsRFC4380()) {
return ~ReadBE32(std::span{m_addr}.last(ADDR_IPV4_SIZE).data());
}
assert(false);
}
7. src/netbase.cpp:128 (src/netbase.cpp:128) — GetNetworkName
case NET_INTERNAL: return "internal";
case NET_MAX: assert(false);
}
assert(false);
}
8. src/outputtype.cpp:78 (src/outputtype.cpp:78) — script-destination helper
case OutputType::BECH32M:
case OutputType::UNKNOWN: {}
}
assert(false);
}
9. src/script/miniscript.h:998 (src/script/miniscript.h:998) — Node::ToString’s upfn lambda
case Fragment::THRESH: {
// ... builds and returns the string ...
return std::move(str) + ")";
}
default: break;
}
assert(false);
};
This is emitted twice: once for StringMaker, once for KeyParser.
10. src/qt/bitcoin.cpp:171 (src/qt/bitcoin.cpp:171) — ErrorSettingsRead
case QMessageBox::Reset:
return false;
case QMessageBox::Abort:
return true;
default:
assert(false);
}
}
11. src/qt/bitcoinunits.cpp:252 (src/qt/bitcoinunits.cpp:252) — FromQint8
case 2: return BitcoinUnit::uBTC;
case 3: return BitcoinUnit::SAT;
}
assert(false);
}
</details>
The godbolt is: https://godbolt.org/z/TE8b8bs8v
Seeing the int3 after the assert still makes me wonder if this is just a false-positive or if this is a violation of the C++26 standard.
C++26 says: https://en.cppreference.com/cpp/error/assert:
If the evaluation yields true, there are no further effects.
Otherwise, assert creates a diagnostic on the standard error stream and calls std::abort().
(since C++26)
And std::abort() says: https://en.cppreference.com/cpp/utility/program/abort:
[[noreturn]] void abort() noexcept;
(since C++11)
But not a blocker. Seems fine to progress here.
<!---
self note:
• You ran cat reproduce_int3.cpp
└ // Minimal stand-in for the MSVC CRT's debug assert expansion. The installed
// clang-cl does not have the Windows SDK/UCRT headers, so declare _wassert
// directly. The macro form matches the CRT's assertion expression.
#if defined(ASSERT_NORETURN)
#define ASSERT_NORETURN_SPEC , noreturn
#else
#define ASSERT_NORETURN_SPEC
#endif
extern "C" __declspec(dllimport ASSERT_NORETURN_SPEC) void __cdecl _wassert(
const wchar_t*, const wchar_t*, unsigned);
#define WIDEN_1(x) L##x
#define WIDEN(x) WIDEN_1(x)
#define assert(expr) ((void)(!!(expr) || (_wassert(WIDEN(#expr), WIDEN(__FILE__), __LINE__), 0)))
bool f(signed char n)
{
switch (n) {
case 0: return false;
case 1: return true;
}
assert(false);
}
Worked for <1s • 11:30 AM
• You ran clang-cl /nologo /std:c++17 /Od /c /UASSERT_NORETURN /FA /Fareproduce_int3.asm reproduce_int3.cpp && grep -C1 _wassert reproduce_int3.asm
└ mov r8d, 23
call qword ptr [rip + __imp__wassert]
ud2
reproduce_int3.cpp(24,1): warning: non-void function does not return a value in all control paths [-Wreturn-type]
24 | }
| ^
1 warning generated.
Worked for <1s • 11:31 AM
• You ran clang-cl /nologo /std:c++17 /O1 /c /UASSERT_NORETURN /FA /Fareproduce_int3.asm reproduce_int3.cpp && grep -C1 _wassert reproduce_int3.asm
└ mov r8d, 23
call qword ptr [rip + __imp__wassert]
int3
reproduce_int3.cpp(24,1): warning: non-void function does not return a value in all control paths [-Wreturn-type]
24 | }
| ^
1 warning generated.
Worked for <1s • 11:31 AM
• You ran clang-cl /nologo /std:c++17 /Od /c /DASSERT_NORETURN /FA /Fareproduce_int3.asm reproduce_int3.cpp && grep -C1 _wassert reproduce_int3.asm
└ mov r8d, 23
call qword ptr [rip + __imp__wassert]
.LBB0_4:
Worked for <1s • 11:31 AM
• You ran clang-cl /nologo /std:c++17 /O1 /c /DASSERT_NORETURN /FA /Fareproduce_int3.asm reproduce_int3.cpp && grep -C1 _wassert reproduce_int3.asm
└ mov r8d, 23
call qword ptr [rip + __imp__wassert]
int3