summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-06-15 19:06:21 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-06-15 19:06:21 -0400
commitdd89227a9f97ec769a8f5f561482288497a72fe7 (patch)
treed522c0093358d308101c85a920633230db144d99
parent6fc9027d5cb0b7218cb4223e2a1c0ca9cf9164ab (diff)
Make void functions return a dummy value.
This means void and non-void functions are called the same way, which means non-void functions can be cast to void functions.
-rw-r--r--graph.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/graph.c b/graph.c
index 5ddabd8..837a2d8 100644
--- a/graph.c
+++ b/graph.c
@@ -52,6 +52,23 @@ graph_function (ast_function_definition_t *function)
node = node_insert_after (function->end, node);
node = node_insert_after (function->exit, node);
+
+ if (function->type_spec->common.type == AST_VOID_TYPE)
+ {
+ /* Dummy return value. This is useful because it means
+ * function calls will always leave something on the
+ * stack. That mean void functions are called in the
+ * same way as non-void functions, and that makes
+ * it possible to cast non-void function pointers to
+ * void function pointers
+ */
+ value_t value;
+
+ value.int32_val = 0;
+
+ node = node_new_literal (value, function->type_spec, node, ast);
+ }
+
node = node_new_return (function->return_type, node, ast);
node->common.reachable = TRUE;
}
@@ -276,7 +293,6 @@ graph_expression (ast_expression_t *expr,
g_assert (id->definition);
node = generate_load (id->definition, expr, FALSE, node, ast);
-
break;
case AST_INT_LITERAL_EXPRESSION:
@@ -710,9 +726,7 @@ graph_statement (ast_statement_t *statement,
case AST_EXPRESSION_STATEMENT:
node = graph_expression (statement->expression.expr, node);
-
- if (statement->expression.expr->common.type_spec->common.type != AST_VOID_TYPE)
- node = node_new_pop (node, ast);
+ node = node_new_pop (node, ast);
break;
case AST_RETURN_STATEMENT: