https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100825
Nickolay Merkin <nickolay.merkin at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |nickolay.merkin at gmail dot com --- Comment #8 from Nickolay Merkin <nickolay.merkin at gmail dot com> --- (In reply to Jonathan Wakely from comment #3) > Clang and EDG agree with GCC here. > > I think your code is ill-formed due to [temp.constr.atomic] p3: > > "If, at different points in the program, the satisfaction result is > different for identical atomic constraints and template arguments, the > program is ill-formed, no diagnostic required." Of course the constraints are different! First constraint is empty, second is always-true. So, these are different overloads. Okay, let's help the compiler giving different mangled names: https://gcc.godbolt.org/z/K8d9vv8oT namespace a {} namespace b {} using namespace a; using namespace b; namespace a { template<class T> void f() { std::cout << __PRETTY_FUNCTION__ << std::endl; } } void g() { f<int>(); } namespace b { template<class T> void f() requires true { std::cout << __PRETTY_FUNCTION__ << std::endl; } } void h() { f<int>(); } g addresses to a::f, h addresses to b::f. Is this still "ill-formed, no diagnostics required"? Does it mean that a compiler may produce any corrupted binary code with any undefined behavior? Just because we wrote same "f<int>()" both times? I believe, not, it does not. The program is well-formed. Both overloads are valid. And both are different, - it is not an ODR violation. So, the issue is on the compiler's side: wrong rules of mangling.