Basically good, but currently I have a small concern here.

In semantic processing, calling `Expression::semantic` or `Statement::semantic` may occur some AST rewriting as side effect. In here, `s->semantic(sc)` may rewrite the type of expression referred by `exp` (although the possibility is low).

So, I'd recommend to move this error reporting to the start of this if block. Then this `if` block would become as:

```cpp
    if (exp && tbret->ty == Tvoid && !implicit0)
    {
        if (exp->type->ty != Tvoid)
        {
            error("cannot return non-void from void function");
        }

        /* Replace:
         *      return exp;
         * with:
         *      exp; return;
         */
        Expression *ce = new CastExp(loc, exp, Type::tvoid);
        Statement *s = new ExpStatement(loc, ce);
        s = s->semantic(sc);

        exp = NULL;
        return new CompoundStatement(loc, s, this);
    }
```