aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-12-05 23:35:34 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-12-10 23:26:23 +0100
commitf9b443940a8515132035435d3b4fec232a26c582 (patch)
tree2edcc10307c116625e24b01c87358f8b57cbe84d
parentaa42d419661df95820ba8c28e93b0b1359e0f8d7 (diff)
downloadsparse-f9b443940a8515132035435d3b4fec232a26c582.tar.gz
fix addressability marking in evaluate_addressof()
mark_addressable() is used to track if a symbol has its address taken but does not take in account the fact that a symbol can be accessed via one of its subfields. A failure occurs in case like: struct { int a; } s = { 3 }; ... def(&s.a); return s.a; where 's' is not marked as being addressable and so the the initializer will be expanded and the return expression will always be replaced by 3, while def() can redefine it. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--evaluate.c2
-rw-r--r--validation/eval/addressable-complex.c1
2 files changed, 2 insertions, 1 deletions
diff --git a/evaluate.c b/evaluate.c
index d78de2ed..c0281e9b 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1542,6 +1542,8 @@ static int compatible_argument_type(struct expression *expr, struct symbol *targ
static void mark_addressable(struct expression *expr)
{
+ while (expr->type == EXPR_BINOP && expr->op == '+')
+ expr = expr->left;
if (expr->type == EXPR_SYMBOL) {
struct symbol *sym = expr->symbol;
sym->ctype.modifiers |= MOD_ADDRESSABLE;
diff --git a/validation/eval/addressable-complex.c b/validation/eval/addressable-complex.c
index 62ab59f0..e3d4aca4 100644
--- a/validation/eval/addressable-complex.c
+++ b/validation/eval/addressable-complex.c
@@ -16,7 +16,6 @@ int use1(void)
/*
* check-name: eval/addressable-complex
* check-command: test-linearize -Wno-decl -fdump-ir $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-contains: load\\.