Before this patch the parameters mentioned in the title weren't
handled by ODRHash, when a hash was generated for a template
specialization.
As a result, multiple different template specializations ended up
getting the same hash, assuming they are identical.
For example:
template <int> void f(){}; template <> void f<1>(){}; template <> void f<2>(){};
f<1> and f<2> are different specializations, so they should
have different hash values. However because of the following
snippet, the value of the template argument was ignored, so
both specializations were treated as if they were identical.
void ODRHash::AddTemplateArgument(TemplateArgument TA) { ... case TemplateArgument::NullPtr: case TemplateArgument::Integral: break; ... }
The same happend in a different situation with pointers. E.g.:
static int x; template <int *> void f(){}; template <> void f<&x>(){}; template <> void f<nullptr>(){};
This patch makes sure, these situations are handled according to
the standard.
[N4849 13.6] (2) Two values are template-argument-equivalent if they are of the same type and (2.1) - they are of integral type and their values are the same, or (2.3) - they are of type std::nullptr_t, or (2.5) - they are of pointer type and they have the same pointer value, or
Actually, looking again, 'getLimitedValue' here is probably a bad change. We allow _BitInt of sizes greater than 64 bits to be a NTTP. https://godbolt.org/z/bGbKvoa38
We should probably do a bit of looping through 64 bit chunks.