There was an error in the bit arithmatic for the can id.
Basically, if the 15th bit of the id was set, then the upper 16bits were 1 less than they should be.
e.g. 0x0001(8-F)XXX -> 0x0000(8-F)XXX
e.g. 0x0000(8-F)XXX -> 0xFFFF(8-F)XXX
The offending operation is (tbufdata[MCP_EID8]<<8). This promotes an unsigned char to a signed int, which results in the corrupted ids. The fix is to cast it to an unsigned int. Note that int's are 16 bit on avr.
It took me a while to figure this out, but the SPICS pin is not necessarily initialized to output when the arduino starts. Explicitly making it an output in the begin() method saves the library user from having to set the pin as output in their code (which they may not know they need to do, since it is not in the example code).
Checking CAN.checkReceive() agains MC_STAT_RXIF_MASK doesn't seem to make sense, it was confusing to me because the code seemed to be using equality with a mask. Since checkReceive() actually returns CAN_MSGAVAIL or CAN_NOMSG, Comparison with CAN_MSGAVAIL seemed more informative than MC_STAT_RXIF_MASK.