Effectively, the rule is that you can't jump into a block past a declaration that has an initialization (or past the declaration of a non-POD type variable). The C++ standard says (C++03 §6.7):
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps(77) from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer (8.5).
(*) The transfer from the condition of a switch statement to a case label is considered a jump in this respect.
int newVal = 42; is a declaration that has an initializer (the = 42 part). The program is ill-formed because if val is 1 or 2, you'll jump into the switch block past the initialization.
int newVal2; is also a declaration; because int is a POD type and the declaration has no initializer, you can jump past this declaration.