Skip to content

Commit ed0ff90

Browse files
committed
Fix the behavior of local array initializer
After observing the implementation of cfront, it appears that the local array initializer may not generate correct instructions to initialize all elements. For example, consider the following code: int main() { int a[5] = {5, 10}; return a[0] + a[1] + a[2] + a[3] + a[4] } If the number of elements in the initializer-list is less than the size of array, the generated instructions only initialize the first elements. The remaining elements are left uninitialized, which may cause the return value in the above example to differ from the expected 15. When the initializer-list is empty, all elements remain uninitialized. Therefore, this commit improves the cfront to generate more instructions to initialize all elements of an array exactly.
1 parent ad2dafc commit ed0ff90

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
@@ -1255,6 +1255,49 @@ void parse_array_init(var_t *var,
12551255
break;
12561256
}
12571257
}
1258+
1259+
if (parent != GLOBAL_BLOCK && emit_code && !is_implicit) {
1260+
/* e.g.:
1261+
*
1262+
* 1.
1263+
* int main() {
1264+
* int a[5] = {};
1265+
* return a[0] + a[1] + a[2] + a[3] + a[4];
1266+
* }
1267+
*
1268+
* 2.
1269+
* int main() {
1270+
* int a[5] = {5, 10}
1271+
* return a[0] + a[1] + a[2] + a[3] + a[4];
1272+
* }
1273+
*
1274+
* The initializer should set the value of the first elements, and
1275+
* initialize other elements without explicit assignments to 0.
1276+
*
1277+
* Therefore, the first and second cases return 0 and 15, respectively.
1278+
* */
1279+
for (; count < var->array_size; count++) {
1280+
var_t *val = require_var(parent);
1281+
gen_name_to(val->var_name);
1282+
val->init_val = 0;
1283+
add_insn(parent, *bb, OP_load_constant, val, NULL, NULL, 0, NULL);
1284+
1285+
var_t target = {0};
1286+
target.type = var->type;
1287+
target.ptr_level = 0;
1288+
var_t *v = resize_var(parent, bb, val, &target);
1289+
1290+
var_t *elem_addr = compute_element_address(parent, bb, base_addr,
1291+
count, elem_size);
1292+
1293+
if (elem_size <= 4) {
1294+
add_insn(parent, *bb, OP_write, NULL, elem_addr, v, elem_size,
1295+
NULL);
1296+
} else {
1297+
fatal("Unsupported: struct assignment > 4 bytes in array");
1298+
}
1299+
}
1300+
}
12581301
lex_expect(T_close_curly);
12591302

12601303
if (is_implicit) {

0 commit comments

Comments
 (0)