summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/decompiler-ast.inl19
-rw-r--r--src/decompiler.cc8
2 files changed, 21 insertions, 6 deletions
diff --git a/src/decompiler-ast.inl b/src/decompiler-ast.inl
index 146d6315..b8a02bbc 100644
--- a/src/decompiler-ast.inl
+++ b/src/decompiler-ast.inl
@@ -232,12 +232,19 @@ struct AST {
stack_depth = stack_depth_start;
auto end = stack.size();
assert(end >= start);
- if (return_results && nresults) {
- // Combine nresults into a return statement, for when this is used as
- // a function body.
- // TODO: if this is some other kind of block and >1 value is being
- // returned, probably need some kind of syntax to make that clearer.
- NewNode(NodeType::EndReturn, ExprType::Nop, nullptr, nresults);
+ if (return_results && !stack.empty()) {
+ if (stack.back().etype == ExprType::Return) {
+ if (stack.back().children.empty()) {
+ // Return statement at the end of a void function.
+ stack.pop_back();
+ }
+ } else if (nresults) {
+ // Combine nresults into a return statement, for when this is used as
+ // a function body.
+ // TODO: if this is some other kind of block and >1 value is being
+ // returned, probably need some kind of syntax to make that clearer.
+ NewNode(NodeType::EndReturn, ExprType::Nop, nullptr, nresults);
+ }
}
end = stack.size();
assert(end >= start);
diff --git a/src/decompiler.cc b/src/decompiler.cc
index 936e0553..76d9e873 100644
--- a/src/decompiler.cc
+++ b/src/decompiler.cc
@@ -398,6 +398,14 @@ struct Decompiler {
return WrapChild(args[0], "if (",
") " + std::string(jmp) + " " + bie->var.name());
}
+ case ExprType::Return: {
+ return WrapNAry(args, "return ", "");
+ }
+ case ExprType::Drop: {
+ // Silent dropping of return values is very common, so currently
+ // don't output this.
+ return std::move(args[0]);
+ }
default: {
std::string name;
switch (n.etype) {