When the compiler sees
It interprets the close-curly as the end of the preceding block, just as if the semicolon weren't there. Then it interprets the semicolon as an empty statement, which is terminated by a semicolon just like non-empty statements.
Here's an extreme example. A source file could look like this:
The compiler consider this to be ten empty statements. Not a very useful source file, except that it teaches us something about semicolons. Hmmm, so maybe it is useful after all.