2 * sparse/smatch_struct_assignment.c
4 * Copyright (C) 2014 Oracle.
6 * Licensed under the Open Software License version 1.1
12 #include "smatch_slist.h"
13 #include "smatch_extra.h"
15 static struct symbol
*get_struct_type(struct expression
*expr
)
19 type
= get_type(expr
);
22 if (type
->type
== SYM_PTR
)
23 type
= get_real_base_type(type
);
24 if (type
&& type
->type
== SYM_STRUCT
)
29 static int known_struct_member_states(struct expression
*expr
)
31 struct state_list
*slist
= __get_cur_slist();
38 if (expr
->type
== EXPR_PREOP
&& expr
->op
== '&')
39 expr
= strip_expr(expr
->unop
);
41 name
= expr_to_var(expr
);
46 FOR_EACH_PTR(slist
, sm
) {
47 if (sm
->owner
!= SMATCH_EXTRA
)
49 cmp
= strncmp(sm
->name
, name
, len
);
53 if (sm
->name
[len
] == '.' ||
54 sm
->name
[len
] == '-' ||
55 sm
->name
[len
] == '.') {
62 } END_FOR_EACH_PTR(sm
);
68 static struct expression
*get_matching_member_expr(struct symbol
*left_type
, struct expression
*right
, struct symbol
*left_member
)
70 struct symbol
*struct_type
;
73 if (!left_member
->ident
)
76 struct_type
= get_struct_type(right
);
79 if (struct_type
!= left_type
)
82 if (right
->type
== EXPR_PREOP
&& right
->op
== '&')
83 right
= strip_expr(right
->unop
);
85 if (is_pointer(right
)) {
86 right
= deref_expression(right
);
90 return member_expression(right
, op
, left_member
->ident
);
93 void __struct_members_copy(int mode
, struct expression
*left
, struct expression
*right
)
95 struct symbol
*struct_type
, *tmp
, *type
;
96 struct expression
*left_member
, *right_member
, *assign
;
99 left
= strip_expr(left
);
100 right
= strip_expr(right
);
102 struct_type
= get_struct_type(left
);
106 if (!known_struct_member_states(right
))
109 if (is_pointer(left
)) {
110 left
= deref_expression(left
);
114 FOR_EACH_PTR(struct_type
->symbol_list
, tmp
) {
115 type
= get_real_base_type(tmp
);
116 if (type
&& type
->type
== SYM_ARRAY
)
119 left_member
= member_expression(left
, op
, tmp
->ident
);
124 right_member
= get_matching_member_expr(struct_type
, right
, tmp
);
127 right_member
= right
;
135 if (!get_implied_rl(right_member
, &rl
) || is_whole_rl(rl
))
138 assign
= assign_expression(left_member
, right_member
);
139 __pass_to_client(assign
, ASSIGNMENT_HOOK
);
140 } END_FOR_EACH_PTR(tmp
);
143 void __fake_struct_member_assignments(struct expression
*expr
)
145 __struct_members_copy(COPY_NORMAL
, expr
->left
, expr
->right
);