aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLinus Torvalds <torvalds@home.transmeta.com>2003-04-03 18:57:37 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:00:08 -0700
commit5575747bc9d1064661042c79ce89e13579c303ae (patch)
treeb8b608c035d6f5eac7988b7ea3fc8c64c362e68a
parentb5b3dfdd3989922b71a38e76c037aa30bb8f160a (diff)
downloadsparse-dev-5575747bc9d1064661042c79ce89e13579c303ae.tar.gz
Clean up address-of evaluation, and mark symbols so evaluated
as addressable (and warn if they were claimed to be "register").
-rw-r--r--evaluate.c32
-rw-r--r--show-parse.c2
-rw-r--r--symbol.h1
3 files changed, 26 insertions, 9 deletions
diff --git a/evaluate.c b/evaluate.c
index e817e4bf..ba2ff09f 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -644,6 +644,28 @@ static struct symbol *evaluate_assignment(struct expression *expr)
return expr->ctype;
}
+static struct symbol *evaluate_addressof(struct expression *expr)
+{
+ struct symbol *ctype = expr->unop->ctype;
+ struct symbol *symbol = alloc_symbol(expr->pos, SYM_PTR);
+
+ symbol->ctype.base_type = ctype;
+ symbol->ctype.alignment = POINTER_ALIGNMENT;
+ symbol->bit_size = BITS_IN_POINTER;
+ expr->ctype = symbol;
+ if (expr->unop->type == EXPR_SYMBOL) {
+ struct symbol *var = expr->unop->symbol;
+ if (var->ctype.modifiers & MOD_REGISTER) {
+ warn(expr->pos, "register variable and address-of do not mix");
+ var->ctype.modifiers &= ~MOD_REGISTER;
+ }
+ var->ctype.modifiers |= MOD_ADDRESSABLE;
+ }
+ return symbol;
+}
+
+
+
static struct symbol *evaluate_preop(struct expression *expr)
{
struct symbol *ctype = expr->unop->ctype;
@@ -675,14 +697,8 @@ static struct symbol *evaluate_preop(struct expression *expr)
expr->ctype = ctype;
return ctype;
- case '&': {
- struct symbol *symbol = alloc_symbol(expr->pos, SYM_PTR);
- symbol->ctype.base_type = ctype;
- symbol->ctype.alignment = POINTER_ALIGNMENT;
- symbol->bit_size = BITS_IN_POINTER;
- expr->ctype = symbol;
- return symbol;
- }
+ case '&':
+ return evaluate_addressof(expr);
case '!':
expr->ctype = &bool_ctype;
diff --git a/show-parse.c b/show-parse.c
index 91289fb0..8fc922ca 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -33,7 +33,7 @@ const char *modifier_string(unsigned long mod)
"const", "volatile", "[signed]", "[unsigned]",
"[char]", "[short]", "[long]", "[long]",
"[typdef]", "[structof]", "[unionof]", "[enum]",
- "[typeof]", "[attribute]", "inline", "<80000>",
+ "[typeof]", "[attribute]", "inline", "[addressable]",
"[nocast]", "[noderef]",
NULL
};
diff --git a/symbol.h b/symbol.h
index a56972ad..c254aa49 100644
--- a/symbol.h
+++ b/symbol.h
@@ -111,6 +111,7 @@ struct symbol {
#define MOD_TYPEOF 0x10000
#define MOD_ATTRIBUTE 0x20000
#define MOD_INLINE 0x40000
+#define MOD_ADDRESSABLE 0x80000
#define MOD_NOCAST 0x100000
#define MOD_NODEREF 0x200000