Print this page
new smatch
@@ -48,18 +48,58 @@
return NULL;
return alloc_string(arg->string->data);
}
+static int xxx_is_array(struct expression *expr)
+{
+ struct symbol *type;
+
+ expr = strip_expr(expr);
+ if (!expr)
+ return 0;
+
+ if (expr->type == EXPR_PREOP && expr->op == '*') {
+ expr = strip_expr(expr->unop);
+ if (!expr)
+ return 0;
+ if (expr->type == EXPR_BINOP && expr->op == '+')
+ return 1;
+ }
+
+ if (expr->type != EXPR_BINOP || expr->op != '+')
+ return 0;
+
+ type = get_type(expr->left);
+ if (!type)
+ return 0;
+ if (type->type != SYM_ARRAY && type->type != SYM_PTR)
+ return 0;
+
+ return 1;
+}
+
+static struct expression *xxx_get_array_base(struct expression *expr)
+{
+ if (!xxx_is_array(expr))
+ return NULL;
+ expr = strip_expr(expr);
+ if (expr->type == EXPR_PREOP && expr->op == '*')
+ expr = strip_expr(expr->unop);
+ if (expr->type != EXPR_BINOP || expr->op != '+')
+ return NULL;
+ return strip_parens(expr->left);
+}
+
static char *get_array_ptr(struct expression *expr)
{
struct expression *array;
struct symbol *type;
char *name;
char buf[256];
- array = get_array_base(expr);
+ array = xxx_get_array_base(expr);
if (array) {
name = get_member_name(array);
if (name)
return name;
@@ -76,11 +116,11 @@
snprintf(buf, sizeof(buf), "%s[]", name);
return alloc_string(buf);
}
expr = get_assigned_expr(expr);
- array = get_array_base(expr);
+ array = xxx_get_array_base(expr);
if (!array)
return NULL;
name = expr_to_var(array);
if (!name)
return NULL;
@@ -139,11 +179,11 @@
char *get_fnptr_name(struct expression *expr)
{
char *name;
- if (is_zero(expr))
+ if (expr_is_zero(expr))
return NULL;
expr = strip_expr(expr);
/* (*ptrs[0])(a, b, c) is the same as ptrs[0](a, b, c); */
@@ -253,10 +293,16 @@
if (type->type == SYM_PTR || type->type == SYM_ARRAY) {
type = get_real_base_type(type);
if (!type)
return 0;
}
+ /* pointer to a pointer */
+ if (type->type == SYM_PTR || type->type == SYM_ARRAY) {
+ type = get_real_base_type(type);
+ if (!type)
+ return 0;
+ }
if (type->type == SYM_FN)
return 1;
if (type == &ulong_ctype && expr->type == EXPR_DEREF)
return 1;
if (type == &void_ctype)
@@ -277,11 +323,12 @@
right = strip_expr(expr->right);
if (right->type == EXPR_PREOP && right->op == '&')
right = strip_expr(right->unop);
if (right->type != EXPR_SYMBOL &&
- right->type != EXPR_DEREF)
+ right->type != EXPR_DEREF &&
+ right->type != EXPR_CALL)
return;
if (!can_hold_function_ptr(right) ||
!can_hold_function_ptr(expr->left))
return;