@@ -47,8 +47,7 @@ void parse_array_init(var_t *var,
4747 bool emit_code );
4848void parse_array_compound_literal (var_t * var ,
4949 block_t * parent ,
50- basic_block_t * * bb ,
51- bool emit_code );
50+ basic_block_t * * bb );
5251
5352label_t * find_label (char * name )
5453{
@@ -1335,8 +1334,7 @@ void parse_array_init(var_t *var,
13351334
13361335void parse_array_compound_literal (var_t * var ,
13371336 block_t * parent ,
1338- basic_block_t * * bb ,
1339- bool emit_code )
1337+ basic_block_t * * bb )
13401338{
13411339 int elem_size = var -> type -> size ;
13421340 int count = 0 ;
@@ -1349,16 +1347,16 @@ void parse_array_compound_literal(var_t *var,
13491347 var_t * value = opstack_pop ();
13501348 if (count == 0 )
13511349 var -> init_val = value -> init_val ;
1352- if ( emit_code ) {
1353- var_t target = {0 };
1354- target .type = var -> type ;
1355- target .ptr_level = 0 ;
1356- var_t * store_val = resize_var (parent , bb , value , & target );
1357- var_t * elem_addr =
1358- compute_element_address (parent , bb , var , count , elem_size );
1359- add_insn (parent , * bb , OP_write , NULL , elem_addr , store_val ,
1360- elem_size , NULL );
1361- }
1350+
1351+ var_t target = {0 };
1352+ target .type = var -> type ;
1353+ target .ptr_level = 0 ;
1354+ var_t * store_val = resize_var (parent , bb , value , & target );
1355+ var_t * elem_addr =
1356+ compute_element_address (parent , bb , var , count , elem_size );
1357+ add_insn (parent , * bb , OP_write , NULL , elem_addr , store_val ,
1358+ elem_size , NULL );
1359+
13621360 count ++ ;
13631361 if (!lex_accept (T_comma ))
13641362 break ;
@@ -1385,7 +1383,11 @@ bool is_pointer_like_value(var_t *var)
13851383 return var && (var -> ptr_level || var -> array_size ||
13861384 (var -> type && var -> type -> ptr_level > 0 ));
13871385}
1388-
1386+ /* Lower a compiler-emitted array literal placeholder (".tN" vars holding
1387+ * compound literals) into a scalar temporary when later IR expects a plain
1388+ * value instead of addressable storage. This keeps SSA joins uniform when
1389+ * only one branch originates from an array literal.
1390+ */
13891391var_t * scalarize_array_literal (block_t * parent ,
13901392 basic_block_t * * bb ,
13911393 var_t * array_var ,
@@ -1394,20 +1396,30 @@ var_t *scalarize_array_literal(block_t *parent,
13941396 if (!is_array_literal_placeholder (array_var ))
13951397 return array_var ;
13961398
1399+ /* Array literal placeholders carry the literal's natural type; default to
1400+ * int when the parser left the type unset.
1401+ */
13971402 type_t * literal_type = array_var -> type ? array_var -> type : TY_int ;
13981403 int literal_size = literal_type -> size ;
13991404 if (literal_size <= 0 )
14001405 literal_size = TY_int -> size ;
14011406
1407+ /* A caller-provided hint (e.g., assignment target) dictates the result
1408+ * type when available so we reuse wider/narrower scalar destinations.
1409+ */
14021410 type_t * result_type = hint_type ? hint_type : literal_type ;
14031411 if (!result_type )
14041412 result_type = TY_int ;
14051413
1414+ /* Create a new scalar temporary, giving it a unique name and copying over
1415+ * the literal data so downstream code can treat it like a normal value.
1416+ */
14061417 var_t * scalar = require_typed_var (parent , result_type );
14071418 scalar -> ptr_level = 0 ;
14081419 gen_name_to (scalar -> var_name );
14091420 scalar -> init_val = array_var -> init_val ;
14101421
1422+ /* Materialize the literal data into the scalar temporary via an OP_read. */
14111423 add_insn (parent , * bb , OP_read , scalar , array_var , NULL , literal_size , NULL );
14121424
14131425 return scalar ;
@@ -2159,7 +2171,7 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
21592171 compound_var -> array_size = 0 ;
21602172 add_insn (parent , * bb , OP_allocat , compound_var , NULL , NULL , 0 ,
21612173 NULL );
2162- parse_array_compound_literal (compound_var , parent , bb , true );
2174+ parse_array_compound_literal (compound_var , parent , bb );
21632175
21642176 if (compound_var -> array_size == 0 ) {
21652177 compound_var -> init_val = 0 ;
@@ -3628,10 +3640,19 @@ void read_ternary_operation(block_t *parent, basic_block_t **bb)
36283640 bool true_ptr_like = is_pointer_like_value (true_val );
36293641 bool false_ptr_like = is_pointer_like_value (false_val );
36303642
3643+ /* The ternary result must look like whichever side is pointer-like. If the
3644+ * "true" expression is still a raw array literal but the "false" side is a
3645+ * plain scalar, materialize the literal now so both branches produce
3646+ * comparable scalar SSA values.
3647+ */
36313648 if (true_array && !false_ptr_like )
36323649 true_val = scalarize_array_literal (parent , & then_ , true_val ,
36333650 false_val ? false_val -> type : NULL );
36343651
3652+ /* Apply the same conversion symmetrically when only the false branch is a
3653+ * literal array. This prevents OP_assign from trying to move array storage
3654+ * into a scalar destination later in code generation.
3655+ */
36353656 if (false_array && !true_ptr_like )
36363657 false_val = scalarize_array_literal (parent , & else_ , false_val ,
36373658 true_val ? true_val -> type : NULL );
0 commit comments