Skip to content

Commit f8f452b

Browse files
committed
Fix the behavior of local array initializer
1 parent d835bc0 commit f8f452b

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/parser.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,49 @@ void parse_array_init(var_t *var,
11641164
break;
11651165
}
11661166
}
1167+
1168+
if (parent != GLOBAL_BLOCK && emit_code && !is_implicit) {
1169+
/* e.g.:
1170+
*
1171+
* 1.
1172+
* int main() {
1173+
* int a[5] = {};
1174+
* return a[0] + a[1] + a[2] + a[3] + a[4];
1175+
* }
1176+
*
1177+
* 2.
1178+
* int main() {
1179+
* int a[5] = {5, 10}
1180+
* return a[0] + a[1] + a[2] + a[3] + a[4];
1181+
* }
1182+
*
1183+
* The initializer should set the value of the first elements, and
1184+
* initialize other elements without explicit assignments to 0.
1185+
*
1186+
* Therefore, the first and second cases return 0 and 15, respectively.
1187+
* */
1188+
for (; count < var->array_size; count++) {
1189+
var_t *val = require_var(parent);
1190+
gen_name_to(val->var_name);
1191+
val->init_val = 0;
1192+
add_insn(parent, *bb, OP_load_constant, val, NULL, NULL, 0, NULL);
1193+
1194+
var_t target = {0};
1195+
target.type = var->type;
1196+
target.ptr_level = 0;
1197+
var_t *v = resize_var(parent, bb, val, &target);
1198+
1199+
var_t *elem_addr = compute_element_address(parent, bb, base_addr,
1200+
count, elem_size);
1201+
1202+
if (elem_size <= 4) {
1203+
add_insn(parent, *bb, OP_write, NULL, elem_addr, v, elem_size,
1204+
NULL);
1205+
} else {
1206+
fatal("Unsupported: struct assignment > 4 bytes in array");
1207+
}
1208+
}
1209+
}
11671210
lex_expect(T_close_curly);
11681211

11691212
if (is_implicit) {

0 commit comments

Comments
 (0)