aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/expand.c
diff options
authorAlexander Viro <viro@www.linux.org.uk>2004-08-12 19:22:24 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:02:45 -0700
commitd77cf76c6941b34eb45dd08ea0aa5febbe07c700 (patch)
tree10b822e7110b1d9967eaec5d0de83c7b7d0f988d /expand.c
parent404a8fc038037d1775861b9f7c921ada7c91c7d6 (diff)
downloadsparse-dev-d77cf76c6941b34eb45dd08ea0aa5febbe07c700.tar.gz
[PATCH] handling of non-lvalue compound objects
Handling of non-lvalue compound objects: We introduce a new primitive - EXPR_SLICE. Meaning is "that many bits from that offset in that non-lvalue struct or union". It is used when we try to get a member out of a non-lvalue struct or union (subsequent .<field> just narrow the slice). And as far as scalar, struct and union fields count, that's it. The only subtle point is handling of array fields. And there I'm doing what C99 requires - they *do* decay to real, honest pointers, causing a copy of object to memory if needed. We get an anonymous object that lives until the next sequence point; optimizer is certainly free to get rid of it completely if it can make do with the value we'd copied there. Note that you _are_ allowed to say foo().a[1] = 0; It doesn't make sense, since the value you've assigned will be immediately lost (and any optimizer will turn that into f()), but it is legitimate and it avoids a *lot* of PITA in describing semantics. It covers only array decay - any other member of non-lvalue struct or union is *not* an lvalue and in struct foo {int x; int y[2];}; struct foo a(void); ... a().x = 0; /* not allowed, non-lvalue */ a().y[0] = 1; /* allowed, but pointless */ you will get an error from the first assignment, but not from the second one. Signed-off-by: Al Viro <viro@parcelfarce.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'expand.c')
-rw-r--r--expand.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/expand.c b/expand.c
index 4e516f80..f38ccf6c 100644
--- a/expand.c
+++ b/expand.c
@@ -754,6 +754,9 @@ static int expand_expression(struct expression *expr)
case EXPR_INDEX:
return UNSAFE;
+ case EXPR_SLICE:
+ return expand_expression(expr->base) + 1;
+
case EXPR_POS:
return expand_expression(expr->init_expr);