Print this page
11972 resync smatch
*** 48,65 ****
return NULL;
return alloc_string(arg->string->data);
}
static char *get_array_ptr(struct expression *expr)
{
struct expression *array;
struct symbol *type;
char *name;
char buf[256];
! array = get_array_base(expr);
if (array) {
name = get_member_name(array);
if (name)
return name;
--- 48,105 ----
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 = xxx_get_array_base(expr);
if (array) {
name = get_member_name(array);
if (name)
return name;
*** 76,86 ****
snprintf(buf, sizeof(buf), "%s[]", name);
return alloc_string(buf);
}
expr = get_assigned_expr(expr);
! array = get_array_base(expr);
if (!array)
return NULL;
name = expr_to_var(array);
if (!name)
return NULL;
--- 116,126 ----
snprintf(buf, sizeof(buf), "%s[]", name);
return alloc_string(buf);
}
expr = get_assigned_expr(expr);
! array = xxx_get_array_base(expr);
if (!array)
return NULL;
name = expr_to_var(array);
if (!name)
return NULL;
*** 139,149 ****
char *get_fnptr_name(struct expression *expr)
{
char *name;
! if (is_zero(expr))
return NULL;
expr = strip_expr(expr);
/* (*ptrs[0])(a, b, c) is the same as ptrs[0](a, b, c); */
--- 179,189 ----
char *get_fnptr_name(struct expression *expr)
{
char *name;
! 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,262 ****
--- 293,308 ----
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,287 ****
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)
return;
if (!can_hold_function_ptr(right) ||
!can_hold_function_ptr(expr->left))
return;
--- 323,334 ----
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_CALL)
return;
if (!can_hold_function_ptr(right) ||
!can_hold_function_ptr(expr->left))
return;