aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLinus Torvalds <torvalds@home.osdl.org>2003-07-09 00:06:13 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:00:55 -0700
commit06231a22afbbad21dcf7523fbf7ed4beb356cd19 (patch)
tree98f6c7b5634675769b947a06783dd9c7867b4361
parentbca6859f6ede2e32dc95365a81d7cadd5686a1f3 (diff)
downloadsparse-dev-06231a22afbbad21dcf7523fbf7ed4beb356cd19.tar.gz
Now that inlining works, make the return handling work properly too,
ie make sure that we don't just go to the right place, but that we also assign the return value to the return variable, and we make inline functions evaluate properly to the value.
-rw-r--r--evaluate.c8
-rw-r--r--parse.c5
-rw-r--r--show-parse.c68
3 files changed, 51 insertions, 30 deletions
diff --git a/evaluate.c b/evaluate.c
index 40139d72..b0aa888f 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -886,8 +886,8 @@ static struct symbol *evaluate_assignment(struct expression *expr)
if (!compatible_assignment_types(expr, ltype, &expr->right, rtype, "assignment"))
return 0;
- expr->ctype = expr->left->ctype;
- return expr->ctype;
+ expr->ctype = ltype;
+ return ltype;
}
static struct symbol *evaluate_addressof(struct expression *expr)
@@ -1580,6 +1580,9 @@ struct symbol *evaluate_symbol(struct symbol *sym)
{
struct symbol *base_type;
+ if (!sym)
+ return sym;
+
sym = examine_symbol_type(sym);
base_type = sym->ctype.base_type;
if (!base_type)
@@ -1684,6 +1687,7 @@ struct symbol *evaluate_statement(struct statement *stmt)
case STMT_COMPOUND: {
struct symbol *type = NULL;
symbol_iterate(stmt->syms, evaluate_one_symbol, NULL);
+ evaluate_symbol(stmt->ret);
statement_iterate(stmt->stmts, evaluate_one_statement, &type);
return type;
}
diff --git a/parse.c b/parse.c
index 81f6334a..bb92010b 100644
--- a/parse.c
+++ b/parse.c
@@ -672,9 +672,12 @@ static struct statement *start_function(struct symbol *sym)
start_function_scope();
ret = alloc_symbol(sym->pos, SYM_NODE);
ret->ident = &return_ident;
- ret->ctype = sym->ctype;
+ ret->ctype = sym->ctype.base_type->ctype;
+ ret->ctype.modifiers &= ~(MOD_STORAGE | MOD_CONST | MOD_VOLATILE | MOD_INLINE | MOD_ADDRESSABLE | MOD_NOCAST | MOD_NODEREF | MOD_ACCESSED | MOD_TOPLEVEL);
+ ret->ctype.modifiers |= (MOD_AUTO | MOD_REGISTER);
bind_symbol(ret, &return_ident, NS_ITERATOR);
stmt->ret = ret;
+
fn_local_symbol(ret);
return stmt;
}
diff --git a/show-parse.c b/show-parse.c
index f05309ae..bb98f83b 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -23,6 +23,8 @@
#include "expression.h"
#include "target.h"
+static int show_symbol_expr(struct symbol *sym);
+
static void do_debug_symbol(struct symbol *sym, int indent)
{
static const char indent_string[] = " ";
@@ -305,11 +307,18 @@ void show_symbol(struct symbol *sym)
symbol_iterate(type->symbol_list, show_struct_member, NULL);
break;
- case SYM_FN:
- printf("\n");
- show_statement(type->stmt);
- printf("\tret\n");
+ case SYM_FN: {
+ struct statement *stmt = type->stmt;
+ if (stmt) {
+ int val;
+ printf("\n");
+ val = show_statement(stmt);
+ if (val)
+ printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
+ printf("\tret\n");
+ }
break;
+ }
default:
break;
@@ -321,22 +330,14 @@ void show_symbol(struct symbol *sym)
}
}
-static int show_return_stmt(struct statement *stmt)
-{
- struct expression *expr = stmt->ret_value;
- struct symbol *target = stmt->ret_target;
+static int show_symbol_init(struct symbol *sym);
- if (expr && expr->ctype) {
- int val = show_expression(expr);
- printf("\tmov.%d\t\tretval,v%d\n",
- expr->ctype->bit_size, val);
- }
- printf("\tgoto .L%p\n", target);
- return 0;
+static int new_pseudo(void)
+{
+ static int nr = 0;
+ return ++nr;
}
-static int show_symbol_init(struct symbol *sym);
-
static int new_label(void)
{
static int label = 0;
@@ -396,6 +397,8 @@ static void show_symbol_decl(struct symbol_list *syms)
} END_FOR_EACH_PTR;
}
+static int show_return_stmt(struct statement *stmt);
+
/*
* Print out a statement
*/
@@ -414,8 +417,14 @@ int show_statement(struct statement *stmt)
FOR_EACH_PTR(stmt->stmts, s) {
last = show_statement(s);
} END_FOR_EACH_PTR;
- if (stmt->ret)
+ if (stmt->ret) {
+ int addr, bits;
printf(".L%p:\n", stmt->ret);
+ addr = show_symbol_expr(stmt->ret);
+ bits = stmt->ret->bit_size;
+ last = new_pseudo();
+ printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
+ }
return last;
}
@@ -547,12 +556,6 @@ void show_expression_list(struct expression_list *list, const char *sep)
expression_iterate(list, show_one_expression, (void *)sep);
}
-static int new_pseudo(void)
-{
- static int nr = 0;
- return ++nr;
-}
-
static int show_call_expression(struct expression *expr)
{
struct symbol *direct;
@@ -686,7 +689,20 @@ static int show_assignment(struct expression *expr)
return val;
}
-static int show_symbol_expr(struct symbol *sym);
+static int show_return_stmt(struct statement *stmt)
+{
+ struct expression *expr = stmt->ret_value;
+ struct symbol *target = stmt->ret_target;
+
+ if (expr && expr->ctype) {
+ int val = show_expression(expr);
+ int bits = expr->ctype->bit_size;
+ int addr = show_symbol_expr(target);
+ show_store_gen(bits, val, NULL, addr);
+ }
+ printf("\tgoto .L%p\n", target);
+ return 0;
+}
static int show_initialization(struct symbol *sym, struct expression *expr)
{
@@ -962,5 +978,3 @@ int show_expression(struct expression *expr)
}
return 0;
}
-
-