Your shift "bug" is not a bug at all! The compile is doing PRECISELY what the c/c++ language specification specifies it should do. Your code is the problem, and I could see it the instant I looked at your code.
Rule #1: If you think you've found a compiler bug, you haven't. That goes DOUBLE if the "bug" is in some fundamental capability, like arithmetic. Such a bug could NEVER survive the tortuous regression tests that all gnu compiler releases much go through before release.