The closest thing to the tool you're after would be a static analysis tool (lint is the usual example for C, but doesn't do C++)
http://en.wikipedia.org/wiki/List_of..._code_analysis
however you may not like the results as they flag up anything they find less than ideal about your code. They can often flag portability issues, but they will also find a lot more besides - not necessarily what you're after.
I'm afraid I don't know of a tool that does exactly what you want, but perhaps in future you may want to use the C99 fixed size types (uint8_t, int8_t, uint16_t, int16_t, etc...) to be sure of the size of data you're using (I work in embedded software where we often have this issue). The porting issues you're seeing are usually caused by programmer assumption about the size of a give type; for example the coder may assume that a pointer is the same size as an int, and cast between them, only to find on a new architecture that the cast becomes a truncation and loses information. (Neither C nor C++ guarantees the size of any traditional type, though int is *usually the native bus width of the system and char is usually a byte).
*when using gcc with the -m64 option an int is defined as 32bits on a 64 bit system - so breaks this rule.
Such programmer assumptions would be very difficult for a compiler to spot as the compiler cannot understand what assumptions you're making when writing the code. I think this is why the feature doesn't exist yet (AFAIK).
As regards finding the bugs, cast operations are often a prime suspect. If you've used the c++ style of casting - "xxxxx_cast<>()" then it will be fairly easy to grep for them and hopefully flush out some suspicious code. Other things to watch for, are if you're initialising variables which you use to mask others. For example if you tried to set a variable to all "1s", e.g
unsigned int bitmask = 0xFFFFFFFF;
This would work well for a 32bit int but only set half of a 64bit int. Two ways to do this sort of thing flexibly are:
unsigned int bitmask = static_cast<unsigned int>(-1);
unsigned int bitmask2 = ~0;
which will both set an unsigned var to all "1"s however big or small its type is. To make your mask you can then clear bits individually as required.
Apologies if you know this already - hopefully it will be of some help in future.
Good luck!