Skip to content

Commit 0de5d30

Browse files
committed
Update driver snapshots after decay tests.
Fix IR test failure. Regenerate ARM IR snapshots to reflect the corrected lowering. Restore ARM/RISC-V codegen files to original structure after earlier brace experiment. Treat zero-length array compound literals as constant zero during lowering so scalar uses don't load garbage. Fix coding style according to cubic-dev-ai's suggestion.
1 parent accfedf commit 0de5d30

File tree

7 files changed

+2450
-2089
lines changed

7 files changed

+2450
-2089
lines changed

src/arm-codegen.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
450450
fatal("Unsupported truncation operation with invalid target size");
451451
}
452452
return;
453-
case OP_sign_ext: {
453+
case OP_sign_ext:
454454
/* Decode source size from upper 16 bits */
455455
int source_size = (rm >> 16) & 0xFFFF;
456456
if (source_size == 2) {
@@ -459,7 +459,6 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
459459
/* For other cases, use byte extension (original behavior) */
460460
emit(__sxtb(__AL, rd, rn, 0));
461461
}
462-
}
463462
return;
464463
case OP_cast:
465464
/* Generic cast operation - for now, just move the value */

src/parser.c

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,10 @@ void parse_array_init(var_t *var,
12851285
}
12861286
}
12871287
}
1288-
1288+
/* Parse array compound literal contents: emit element stores to a temporary
1289+
* array. Counts initializers and consumes the closing brace. Used only for
1290+
* array types.
1291+
*/
12891292
void parse_array_compound_literal(var_t *var,
12901293
block_t *parent,
12911294
basic_block_t **bb,
@@ -1300,8 +1303,9 @@ void parse_array_compound_literal(var_t *var,
13001303
read_expr(parent, bb);
13011304
read_ternary_operation(parent, bb);
13021305
var_t *value = opstack_pop();
1303-
if (count == 0)
1306+
if (count == 0) {
13041307
var->init_val = value->init_val;
1308+
}
13051309
if (emit_code) {
13061310
var_t target = {0};
13071311
target.type = var->type;
@@ -1313,19 +1317,21 @@ void parse_array_compound_literal(var_t *var,
13131317
elem_size, NULL);
13141318
}
13151319
count++;
1316-
if (!lex_accept(T_comma))
1320+
if (!lex_accept(T_comma)) {
13171321
break;
1318-
if (lex_peek(T_close_curly, NULL))
1322+
}
1323+
if (lex_peek(T_close_curly, NULL)) {
13191324
break;
1325+
}
13201326
}
13211327
}
13221328

13231329
lex_expect(T_close_curly);
13241330
var->array_size = count;
13251331
}
1326-
/* Identify compiler-emitted temporaries that hold array compound literals.
1327-
* Parsing assigns these temporaries synthetic names via gen_name_to (".tN")
1328-
* and they keep array metadata without pointer indirection.
1332+
/* Detect compiler temporaries ('.tN' names) holding array compound literals.
1333+
* These retain array metadata (size/type) without decaying to pointers until
1334+
* needed.
13291335
*/
13301336
bool is_array_literal_placeholder(var_t *var)
13311337
{
@@ -1341,9 +1347,8 @@ var_t *scalarize_array_literal(block_t *parent,
13411347
if (!is_array_literal_placeholder(array_var))
13421348
return array_var;
13431349

1344-
type_t *elem_type = hint_type ? hint_type : array_var->type;
1345-
if (!elem_type)
1346-
elem_type = TY_int;
1350+
type_t *elem_type =
1351+
hint_type ? hint_type : (array_var->type ? array_var->type : TY_int);
13471352

13481353
int elem_size = elem_type->size;
13491354
if (elem_size <= 0)
@@ -1355,6 +1360,7 @@ var_t *scalarize_array_literal(block_t *parent,
13551360
scalar->init_val = array_var->init_val;
13561361

13571362
add_insn(parent, *bb, OP_read, scalar, array_var, NULL, elem_size, NULL);
1363+
13581364
return scalar;
13591365
}
13601366
void read_inner_var_decl(var_t *vd, bool anon, bool is_param)
@@ -1653,6 +1659,8 @@ void read_func_parameters(func_t *func, block_t *parent, basic_block_t **bb)
16531659
if (param_num < func->num_params) {
16541660
var_t *target = &func->param_defs[param_num];
16551661
if (!target->ptr_level && !target->array_size)
1662+
/* Decay array literals to scalars for non-pointer params,
1663+
* per C semantics. */
16561664
param = scalarize_array_literal(parent, bb, param,
16571665
target->type);
16581666
} else if (func->va_args) {
@@ -2107,6 +2115,14 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
21072115
add_insn(parent, *bb, OP_allocat, compound_var, NULL, NULL, 0,
21082116
NULL);
21092117
parse_array_compound_literal(compound_var, parent, bb, true);
2118+
2119+
if (compound_var->array_size == 0) {
2120+
/* Zero-length arrays default to 0 constant (avoids garbage
2121+
* reads in scalar contexts). */
2122+
compound_var->init_val = 0;
2123+
add_insn(parent, *bb, OP_load_constant, compound_var, NULL,
2124+
NULL, 0, NULL);
2125+
}
21102126
opstack_push(compound_var);
21112127
consumed_close_brace = true;
21122128
} else if (cast_ptr_level > 0) {
@@ -3531,14 +3547,12 @@ void finalize_logical(opcode_t op,
35313547

35323548
void read_ternary_operation(block_t *parent, basic_block_t **bb)
35333549
{
3534-
var_t *vd;
3535-
35363550
if (!lex_accept(T_question))
35373551
return;
35383552

35393553
/* ternary-operator */
3540-
vd = opstack_pop();
3541-
add_insn(parent, *bb, OP_branch, NULL, vd, NULL, 0, NULL);
3554+
var_t *condition = opstack_pop();
3555+
add_insn(parent, *bb, OP_branch, NULL, condition, NULL, 0, NULL);
35423556

35433557
basic_block_t *then_ = bb_create(parent);
35443558
basic_block_t *else_ = bb_create(parent);
@@ -3566,17 +3580,21 @@ void read_ternary_operation(block_t *parent, basic_block_t **bb)
35663580
bool false_array = is_array_literal_placeholder(false_val);
35673581

35683582
if (true_array && !false_array)
3583+
/* Scalarize array literals if the other branch isn't pointer-like, to
3584+
* match types. */
35693585
true_val = scalarize_array_literal(parent, &then_, true_val,
35703586
false_val ? false_val->type : NULL);
35713587

35723588
if (false_array && !true_array)
3589+
/* Scalarize array literals if the other branch isn't pointer-like, to
3590+
* match types. */
35733591
false_val = scalarize_array_literal(parent, &else_, false_val,
35743592
true_val ? true_val->type : NULL);
35753593

3576-
vd = require_var(parent);
3577-
gen_name_to(vd->var_name);
3578-
add_insn(parent, then_, OP_assign, vd, true_val, NULL, 0, NULL);
3579-
add_insn(parent, else_, OP_assign, vd, false_val, NULL, 0, NULL);
3594+
var_t *result_var = require_var(parent);
3595+
gen_name_to(result_var->var_name);
3596+
add_insn(parent, then_, OP_assign, result_var, true_val, NULL, 0, NULL);
3597+
add_insn(parent, else_, OP_assign, result_var, false_val, NULL, 0, NULL);
35803598

35813599
var_t *array_ref = NULL;
35823600
if (is_array_literal_placeholder(true_val))
@@ -3585,13 +3603,13 @@ void read_ternary_operation(block_t *parent, basic_block_t **bb)
35853603
array_ref = false_val;
35863604

35873605
if (array_ref) {
3588-
vd->array_size = array_ref->array_size;
3589-
vd->init_val = array_ref->init_val;
3590-
vd->type = array_ref->type;
3606+
result_var->array_size = array_ref->array_size;
3607+
result_var->init_val = array_ref->init_val;
3608+
result_var->type = array_ref->type;
35913609
}
35923610

3593-
vd->is_ternary_ret = true;
3594-
opstack_push(vd);
3611+
result_var->is_ternary_ret = true;
3612+
opstack_push(result_var);
35953613
bb[0] = end_ternary;
35963614
}
35973615

@@ -3737,11 +3755,13 @@ bool read_body_assignment(char *token,
37373755

37383756
read_expr(parent, bb);
37393757

3740-
var_t *rhs_val = opstack_pop();
3758+
var_t *rhs = opstack_pop();
37413759
if (!lvalue.ptr_level && !lvalue.is_reference)
3742-
rhs_val = scalarize_array_literal(parent, bb, rhs_val,
3743-
lvalue.type);
3744-
opstack_push(rhs_val);
3760+
/* Decay RHS array literal to scalar if target is
3761+
* non-pointer (e.g., int x = (int[]){1}; uses first elem).
3762+
*/
3763+
rhs = scalarize_array_literal(parent, bb, rhs, lvalue.type);
3764+
opstack_push(rhs);
37453765
vd = require_var(parent);
37463766
vd->init_val = increment_size;
37473767
gen_name_to(vd->var_name);

0 commit comments

Comments
 (0)