Print this page
12166 resync smatch to 0.6.1-rc1-il-3
@@ -117,10 +117,15 @@
{
struct symbol *type;
struct ident *member;
int offset;
+ /*
+ * FIXME: This doesn't handle foo.u.bar correctly.
+ *
+ */
+
if (expr->type != EXPR_DEREF) /* hopefully, this doesn't happen */
return -1;
if (expr->member_offset >= 0)
return expr->member_offset;
@@ -200,29 +205,70 @@
static struct range_list *where_allocated_rl(struct symbol *sym)
{
if (!sym)
return NULL;
+ /* This should just be the mtag if it's not on the stack */
return alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
}
+static bool handle_fn_address(struct expression *expr, struct range_list **rl)
+{
+ struct symbol *type;
+
+ if (expr->type == EXPR_PREOP && expr->op == '&')
+ expr = strip_expr(expr->unop);
+
+ if (expr->type != EXPR_SYMBOL)
+ return false;
+
+ type = get_type(expr);
+ if (!type || type->type != SYM_FN)
+ return false;
+
+ *rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
+ return true;
+}
+
int get_address_rl(struct expression *expr, struct range_list **rl)
{
struct expression *unop;
+ /*
+ * Ugh... This function is bad. It doesn't work where it's supposed to
+ * and it does more than it really should. It shouldn't handle string
+ * literals I think...
+ *
+ * There are several complications. For arrays and functions the "&foo"
+ * "foo" are equivalent. But the problem is that we're also passing in
+ * foo->array[] and foo->fn.
+ *
+ * Then, when we have foo->bar.baz.one.two; that needs to be handled
+ * correctly but right now, it is not.
+ *
+ */
+
expr = strip_expr(expr);
if (!expr)
return 0;
- if (expr->type == EXPR_STRING) {
- *rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
+ /*
+ * For functions &fn and fn are equivalent. I don't know if this is
+ * really the right place to handle it, but let's just get it out of the
+ * way for now.
+ *
+ */
+ if (handle_fn_address(expr, rl))
return 1;
- }
- if (expr->type == EXPR_PREOP && expr->op == '&')
+ /*
+ * For arrays, &foo->array and foo->array are equivalent.
+ *
+ */
+ if (expr->type == EXPR_PREOP && expr->op == '&') {
expr = strip_expr(expr->unop);
- else {
+ } else {
struct symbol *type;
type = get_type(expr);
if (!type || type->type != SYM_ARRAY)
return 0;