Nesting `PointerUnion` in `PointerIntPair` overlaps integer bits

I have just tried the following nesting:

using mlir::Value;
using mlir::Attribute;
PointerIntPair<PointerUnion<Value, Attribute>, 1, bool> data;

This seems to overlap the discriminant bit of PointerUnion with the single bit requested for PointerIntPair. The following then does not assert:

// getInt() returns the discriminant
data.setPointer(Value{});
assert(data.getInt() == 0);
data.setPointer(Attribute{});
assert(data.getInt() == 1);

// setInt() swaps the apparent type in the union
data.setPointer(Value{});
assert(isa<Value>(data.getPointer()));
data.setInt(1);
assert(isa<Attribute>(data.getPointer()));

Is this intended behavior or a bug? (Running this on x86_64.) A comment on PointerIntPair suggests that nesting these is actually intended to work (from llvm/ADR/PointerIntPair.h):

/// Note that PointerIntPair always puts the IntVal part in the highest bits
/// possible.  For example, PointerIntPair<void*, 1, bool> will put the bit for
/// the bool into bit #2, not bit #0, which allows the low two bits to be used
/// for something else.  For example, this allows:
///   PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
/// ... and the two bools will land in different bits.
template <typename PointerTy, unsigned IntBits, typename IntType = unsigned,
          typename PtrTraits = PointerLikeTypeTraits<PointerTy>,
          typename Info = PointerIntPairInfo<PointerTy, IntBits, PtrTraits>>
class PointerIntPair {

Clang nests PointerUnion inside PointerIntPair in very heavily used QualType type. I dug into that a while ago, and I think it’s (a) intended to work; (b) correctly allocates 1 bit for PointerUnion discriminator, and then 3 bits to type qualifiers. It is also statically checked that in total you don’t ask for more bits than the smallest alignment allows.