Automatic semicolon insertion
Quoting the specification,
When a continue, break, return, throw, or yield token is encountered and a LineTerminator is encountered before the next token, a semicolon is automatically inserted after the continue, break, return, throw, or yield token.
So the code will become like this
function foo2() {
    return;          // Note the `;` after `return`
    {
        bar: "hello"
    };
}
The return statement terminates and then there is an object after that, which is basically unreachable code. Since the return statement doesn't return anything explicitly, undefined will be returned.