... oops, sent the wrong patch. See the below instead.
Paolo. ///////////////////
Index: cp/parser.c =================================================================== --- cp/parser.c (revision 218348) +++ cp/parser.c (working copy) @@ -10841,6 +10841,7 @@ cp_parser_for_init_statement (cp_parser* parser, t { bool is_range_for = false; bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; + location_t loc = cp_lexer_peek_token (parser->lexer)->location; if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON)) @@ -10881,6 +10882,8 @@ cp_parser_for_init_statement (cp_parser* parser, t "-std=c++11 or -std=gnu++11"); *decl = error_mark_node; } + else if (*decl == error_mark_node) + error_at (loc, "invalid declaration in range-based %<for%> loop"); } else /* The ';' is not consumed yet because we told Index: testsuite/g++.dg/cpp0x/range-for29.C =================================================================== --- testsuite/g++.dg/cpp0x/range-for29.C (revision 0) +++ testsuite/g++.dg/cpp0x/range-for29.C (working copy) @@ -0,0 +1,10 @@ +// PR c++/63985 +// { dg-require-effective-target c++11 } + +int main() +{ + int arr; + for (int i = 5: arr) // { dg-error "invalid declaration" } + return 1; + return 0; +}