Skip to content

Commit f514987

Browse files
committed
Mark local variable writes in value positions as being read
1 parent 4a41d29 commit f514987

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

src/prism.c

+31-10
Original file line numberDiff line numberDiff line change
@@ -1036,8 +1036,8 @@ pm_parser_optional_constant_id_token(pm_parser_t *parser, const pm_token_t *toke
10361036
* If the node is value node, it returns NULL.
10371037
* If not, it returns the pointer to the node to be inspected as "void expression".
10381038
*/
1039-
static pm_node_t*
1040-
pm_check_value_expression(pm_node_t *node) {
1039+
static pm_node_t *
1040+
pm_check_value_expression(pm_parser_t *parser, pm_node_t *node) {
10411041
pm_node_t* void_node = NULL;
10421042

10431043
while (node != NULL) {
@@ -1096,7 +1096,7 @@ pm_check_value_expression(pm_node_t *node) {
10961096
if (cast->statements == NULL || cast->consequent == NULL) {
10971097
return NULL;
10981098
}
1099-
pm_node_t *vn = pm_check_value_expression((pm_node_t *) cast->statements);
1099+
pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->statements);
11001100
if (vn == NULL) {
11011101
return NULL;
11021102
}
@@ -1111,7 +1111,7 @@ pm_check_value_expression(pm_node_t *node) {
11111111
if (cast->statements == NULL || cast->consequent == NULL) {
11121112
return NULL;
11131113
}
1114-
pm_node_t *vn = pm_check_value_expression((pm_node_t *) cast->statements);
1114+
pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->statements);
11151115
if (vn == NULL) {
11161116
return NULL;
11171117
}
@@ -1136,6 +1136,15 @@ pm_check_value_expression(pm_node_t *node) {
11361136
node = cast->left;
11371137
break;
11381138
}
1139+
case PM_LOCAL_VARIABLE_WRITE_NODE: {
1140+
pm_local_variable_write_node_t *cast = (pm_local_variable_write_node_t *) node;
1141+
1142+
pm_scope_t *scope = parser->current_scope;
1143+
for (uint32_t depth = 0; depth < cast->depth; depth++) scope = scope->previous;
1144+
1145+
pm_locals_read(&scope->locals, cast->name);
1146+
return NULL;
1147+
}
11391148
default:
11401149
return NULL;
11411150
}
@@ -1146,7 +1155,7 @@ pm_check_value_expression(pm_node_t *node) {
11461155

11471156
static inline void
11481157
pm_assert_value_expression(pm_parser_t *parser, pm_node_t *node) {
1149-
pm_node_t *void_node = pm_check_value_expression(node);
1158+
pm_node_t *void_node = pm_check_value_expression(parser, node);
11501159
if (void_node != NULL) {
11511160
pm_parser_err_node(parser, void_node, PM_ERR_VOID_EXPRESSION);
11521161
}
@@ -1338,13 +1347,25 @@ static bool
13381347
pm_conditional_predicate_warn_write_literal_p(const pm_node_t *node) {
13391348
switch (PM_NODE_TYPE(node)) {
13401349
case PM_ARRAY_NODE: {
1350+
if (PM_NODE_FLAG_P(node, PM_NODE_FLAG_STATIC_LITERAL)) return true;
1351+
13411352
const pm_array_node_t *cast = (const pm_array_node_t *) node;
1342-
const pm_node_t *element;
1353+
for (size_t index = 0; index < cast->elements.size; index++) {
1354+
if (!pm_conditional_predicate_warn_write_literal_p(cast->elements.nodes[index])) return false;
1355+
}
13431356

1344-
PM_NODE_LIST_FOREACH(&cast->elements, index, element) {
1345-
if (!pm_conditional_predicate_warn_write_literal_p(element)) {
1346-
return false;
1347-
}
1357+
return true;
1358+
}
1359+
case PM_HASH_NODE: {
1360+
if (PM_NODE_FLAG_P(node, PM_NODE_FLAG_STATIC_LITERAL)) return true;
1361+
1362+
const pm_hash_node_t *cast = (const pm_hash_node_t *) node;
1363+
for (size_t index = 0; index < cast->elements.size; index++) {
1364+
const pm_node_t *element = cast->elements.nodes[index];
1365+
if (!PM_NODE_TYPE_P(element, PM_ASSOC_NODE)) return false;
1366+
1367+
const pm_assoc_node_t *assoc = (const pm_assoc_node_t *) element;
1368+
if (!pm_conditional_predicate_warn_write_literal_p(assoc->key) || !pm_conditional_predicate_warn_write_literal_p(assoc->value)) return false;
13481369
}
13491370

13501371
return true;

0 commit comments

Comments
 (0)