smatch_clear_buffer: memcpy() should set the destination to unknown
authorDan Carpenter <dan.carpenter@oracle.com>
Fri, 11 Oct 2013 07:54:10 +0000 (11 10:54 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Fri, 11 Oct 2013 07:54:10 +0000 (11 10:54 +0300)
In the original code "memcpy(foo, bar, sizeof(foo))" was equivalent to
"foo.a = foo.a; foo.b = foo.b;".  Most of the time foo starts as
uninitialized so it's not a problem, but if it's initialized that doesn't
work.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch_clear_buffer.c
smatch_expressions.c
smatch_extra.h

index 3fdd14c..3d9d140 100644 (file)
@@ -90,7 +90,7 @@ static void initialize_struct_members(struct symbol *type, struct expression *ex
                if (to && type_positive_bits(get_type(member)) >= type_positive_bits(get_type(to)))
                        assign = assign_expression(member, to);
                else
-                       assign = assign_expression(member, member);
+                       assign = assign_expression(member, unknown_value_expression(member));
 
                __pass_to_client(assign, ASSIGNMENT_HOOK);
        } END_FOR_EACH_PTR(tmp);
index baa01d0..275c380 100644 (file)
@@ -104,3 +104,43 @@ struct expression *symbol_expression(struct symbol *sym)
        expr->symbol_name = sym->ident;
        return expr;
 }
+
+#define FAKE_NAME "smatch_fake"
+struct ident unknown_value = {
+       .len = sizeof(FAKE_NAME),
+       .name = FAKE_NAME,
+};
+
+static int fake_counter;
+static struct ident *fake_ident()
+{
+       struct ident *ret;
+       char buf[32];
+       int len;
+
+       snprintf(buf, sizeof(buf), "smatch_fake_%d", fake_counter++);
+       len = strlen(buf) + 1;
+       ret = malloc(sizeof(*ret) + len);
+       memset(ret, 0, sizeof(*ret));
+       memcpy(ret->name, buf, len);
+       ret->len = len;
+
+       return ret;
+}
+
+struct expression *unknown_value_expression(struct expression *expr)
+{
+       struct expression *ret;
+       struct symbol *type;
+
+       type = get_type(expr);
+       if (!type || type->type != SYM_BASETYPE)
+               type = &llong_ctype;
+
+       ret = alloc_expression(expr->pos, EXPR_SYMBOL);
+       ret->symbol = alloc_symbol(expr->pos, SYM_BASETYPE);
+       ret->symbol->ctype.base_type = type;
+       ret->symbol_name = fake_ident();
+
+       return ret;
+}
index 937ba88..a7b2704 100644 (file)
@@ -157,6 +157,7 @@ struct expression *assign_expression(struct expression *left, struct expression
 struct expression *binop_expression(struct expression *left, int op, struct expression *right);
 struct expression *array_element_expression(struct expression *array, struct expression *offset);
 struct expression *symbol_expression(struct symbol *sym);
+struct expression *unknown_value_expression(struct expression *expr);
 
 /* smatch_param_limit.c */
 struct smatch_state *get_orig_estate(const char *name, struct symbol *sym);