Skip to content

Commit 34c8aac

Browse files
committed
Fix array compound literal parsing to preserve pointer semantics
Implement proper array compound literal handling that emits element writes, counts initializers, and returns the temporary array pointer instead of collapsing to the first element. This restores correct pointer semantics and avoids discarding array literals during parsing. Struct and scalar compound literals are unchanged. The parser now tracks whether the closing brace was already consumed by the array helper to prevent double reads.
1 parent 4da0b6e commit 34c8aac

File tree

1 file changed

+51
-4
lines changed

1 file changed

+51
-4
lines changed

src/parser.c

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ void parse_array_init(var_t *var,
4545
block_t *parent,
4646
basic_block_t **bb,
4747
bool emit_code);
48-
48+
void parse_array_compound_literal(var_t *var,
49+
block_t *parent,
50+
basic_block_t **bb,
51+
bool emit_code);
4952

5053
label_t *find_label(char *name)
5154
{
@@ -1283,6 +1286,42 @@ void parse_array_init(var_t *var,
12831286
}
12841287
}
12851288

1289+
void parse_array_compound_literal(var_t *var,
1290+
block_t *parent,
1291+
basic_block_t **bb,
1292+
bool emit_code)
1293+
{
1294+
int elem_size = var->type->size;
1295+
int count = 0;
1296+
var->array_size = 0;
1297+
var->init_val = 0;
1298+
if (!lex_peek(T_close_curly, NULL)) {
1299+
for (;;) {
1300+
read_expr(parent, bb);
1301+
read_ternary_operation(parent, bb);
1302+
var_t *value = opstack_pop();
1303+
if (count == 0)
1304+
var->init_val = value->init_val;
1305+
if (emit_code) {
1306+
var_t target = {0};
1307+
target.type = var->type;
1308+
target.ptr_level = 0;
1309+
var_t *store_val = resize_var(parent, bb, value, &target);
1310+
var_t *elem_addr = compute_element_address(
1311+
parent, bb, var, count, elem_size);
1312+
add_insn(parent, *bb, OP_write, NULL, elem_addr, store_val,
1313+
elem_size, NULL);
1314+
}
1315+
count++;
1316+
if (!lex_accept(T_comma))
1317+
break;
1318+
if (lex_peek(T_close_curly, NULL))
1319+
break;
1320+
}
1321+
}
1322+
lex_expect(T_close_curly);
1323+
var->array_size = count;
1324+
}
12861325
void read_inner_var_decl(var_t *vd, bool anon, bool is_param)
12871326
{
12881327
/* Preserve typedef pointer level - don't reset if already inherited */
@@ -2017,9 +2056,16 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
20172056
bool is_array_literal = (cast_ptr_level == -1);
20182057
if (is_array_literal)
20192058
cast_ptr_level = 0; /* Reset for normal processing */
2020-
2059+
bool consumed_close_brace = false;
20212060
/* Check if this is a pointer compound literal */
2022-
if (cast_ptr_level > 0) {
2061+
if (is_array_literal) {
2062+
compound_var->array_size = 0;
2063+
add_insn(parent, *bb, OP_allocat, compound_var, NULL, NULL, 0,
2064+
NULL);
2065+
parse_array_compound_literal(compound_var, parent, bb, true);
2066+
opstack_push(compound_var);
2067+
consumed_close_brace = true;
2068+
} else if (cast_ptr_level > 0) {
20232069
/* Pointer compound literal: (int*){&x} */
20242070
compound_var->ptr_level = cast_ptr_level;
20252071

@@ -2187,7 +2233,8 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
21872233
}
21882234
}
21892235

2190-
lex_expect(T_close_curly);
2236+
if (!consumed_close_brace)
2237+
lex_expect(T_close_curly);
21912238
} else {
21922239
/* Regular parenthesized expression */
21932240
read_expr(parent, bb);

0 commit comments

Comments
 (0)