In strictly conforming C 1990, declarations could appear only at file scope (outside of function definitions) or at the start of a compound statement. The grammar for a compound statement in C 1990 6.6.2 was:
compound-statement
{ declaration-listopt statement-listopt }
That says a compound statement is { followed by zero or more declarations, then zero or more statements, then }. So the declarations had to come first.
In C 1999 6.8.2, this changed to:
compound-statement
{ block-item-listopt }
A block-item-list is a list of block-item, each of which may be a declaration or a statement, so declarations and statements could be freely mixed.
In your example, the declarations int val = i + 1; and int x = val * val; do not appear after executable statements in their compound statement. The compound statement starts with the { immediately before int val = i + 1;, so that declaration is at the start of the compound statement.
Another change was that the for grammar was changed from this in C 1990 6.6.5:
for ( expressionopt ; expressionopt ; expressionopt ) statement
to this choice of two forms in C 1999 6.8.5:
for ( expressionopt ; expressionopt ; expressionopt ) statement
for ( declaration expressionopt ; expressionopt ) statement
(Note the declaration includes a terminating ;.)
That explains why you can have int i = 0 in for(int i = 0; i<=10; i++).