@@ -45,10 +45,6 @@ void parse_array_init(var_t *var,
4545 block_t * parent ,
4646 basic_block_t * * bb ,
4747 bool emit_code );
48- void parse_array_compound_literal (var_t * var ,
49- block_t * parent ,
50- basic_block_t * * bb ,
51- bool emit_code );
5248
5349label_t * find_label (char * name )
5450{
@@ -877,6 +873,7 @@ void parse_array_literal_expr(block_t *parent, basic_block_t **bb)
877873{
878874 var_t * array_var = require_var (parent );
879875 gen_name_to (array_var -> var_name );
876+ array_var -> is_compound_literal = true;
880877
881878 int element_count = 0 ;
882879 var_t * first_element = NULL ;
@@ -1335,8 +1332,7 @@ void parse_array_init(var_t *var,
13351332
13361333void parse_array_compound_literal (var_t * var ,
13371334 block_t * parent ,
1338- basic_block_t * * bb ,
1339- bool emit_code )
1335+ basic_block_t * * bb )
13401336{
13411337 int elem_size = var -> type -> size ;
13421338 int count = 0 ;
@@ -1349,16 +1345,16 @@ void parse_array_compound_literal(var_t *var,
13491345 var_t * value = opstack_pop ();
13501346 if (count == 0 )
13511347 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- }
1348+
1349+ var_t target = {0 };
1350+ target .type = var -> type ;
1351+ target .ptr_level = 0 ;
1352+ var_t * store_val = resize_var (parent , bb , value , & target );
1353+ var_t * elem_addr =
1354+ compute_element_address (parent , bb , var , count , elem_size );
1355+ add_insn (parent , * bb , OP_write , NULL , elem_addr , store_val ,
1356+ elem_size , NULL );
1357+
13621358 count ++ ;
13631359 if (!lex_accept (T_comma ))
13641360 break ;
@@ -1371,13 +1367,13 @@ void parse_array_compound_literal(var_t *var,
13711367 var -> array_size = count ;
13721368}
13731369/* Identify compiler-emitted temporaries that hold array compound literals.
1374- * Parsing assigns these temporaries synthetic names via gen_name_to (".tN")
1375- * and they keep array metadata without pointer indirection .
1370+ * They keep array metadata without pointer indirection and are marked via
1371+ * is_compound_literal when synthesized .
13761372 */
13771373bool is_array_literal_placeholder (var_t * var )
13781374{
13791375 return var && var -> array_size > 0 && !var -> ptr_level &&
1380- var -> var_name [ 0 ] == '.' ;
1376+ var -> is_compound_literal ;
13811377}
13821378
13831379bool is_pointer_like_value (var_t * var )
@@ -1386,6 +1382,11 @@ bool is_pointer_like_value(var_t *var)
13861382 (var -> type && var -> type -> ptr_level > 0 ));
13871383}
13881384
1385+ /* Lower a compiler-emitted array literal placeholder (marked via
1386+ * is_compound_literal) into a scalar temporary when later IR expects a plain
1387+ * value instead of addressable storage. This keeps SSA joins uniform when only
1388+ * one branch originates from an array literal.
1389+ */
13891390var_t * scalarize_array_literal (block_t * parent ,
13901391 basic_block_t * * bb ,
13911392 var_t * array_var ,
@@ -1394,24 +1395,50 @@ var_t *scalarize_array_literal(block_t *parent,
13941395 if (!is_array_literal_placeholder (array_var ))
13951396 return array_var ;
13961397
1398+ /* Array literal placeholders carry the literal's natural type; default to
1399+ * int when the parser left the type unset.
1400+ */
13971401 type_t * literal_type = array_var -> type ? array_var -> type : TY_int ;
13981402 int literal_size = literal_type -> size ;
13991403 if (literal_size <= 0 )
14001404 literal_size = TY_int -> size ;
14011405
1406+ /* A caller-provided hint (e.g., assignment target) dictates the result
1407+ * type when available so we reuse wider/narrower scalar destinations.
1408+ */
14021409 type_t * result_type = hint_type ? hint_type : literal_type ;
14031410 if (!result_type )
14041411 result_type = TY_int ;
14051412
1413+ /* Create a new scalar temporary, giving it a unique name and copying over
1414+ * the literal data so downstream code can treat it like a normal value.
1415+ */
14061416 var_t * scalar = require_typed_var (parent , result_type );
14071417 scalar -> ptr_level = 0 ;
14081418 gen_name_to (scalar -> var_name );
14091419 scalar -> init_val = array_var -> init_val ;
14101420
1421+ /* Materialize the literal data into the scalar temporary via an OP_read. */
14111422 add_insn (parent , * bb , OP_read , scalar , array_var , NULL , literal_size , NULL );
14121423
14131424 return scalar ;
14141425}
1426+
1427+ /* Centralized guard for lowering array literal placeholders when a scalar
1428+ * value is expected, keeping the scattered special cases consistent.
1429+ */
1430+ var_t * scalarize_array_literal_if_needed (block_t * parent ,
1431+ basic_block_t * * bb ,
1432+ var_t * value ,
1433+ type_t * hint_type ,
1434+ bool needs_scalar )
1435+ {
1436+ if (!needs_scalar )
1437+ return value ;
1438+
1439+ return scalarize_array_literal (parent , bb , value , hint_type );
1440+ }
1441+
14151442void read_inner_var_decl (var_t * vd , bool anon , bool is_param )
14161443{
14171444 /* Preserve typedef pointer level - don't reset if already inherited */
@@ -1704,24 +1731,24 @@ void read_func_parameters(func_t *func, block_t *parent, basic_block_t **bb)
17041731 read_ternary_operation (parent , bb );
17051732
17061733 param = opstack_pop ();
1707- if (func ) {
1708- if (param_num < func -> num_params ) {
1709- var_t * target = & func -> param_defs [param_num ];
1710- if (!target -> ptr_level && !target -> array_size )
1711- param = scalarize_array_literal (parent , bb , param ,
1712- target -> type );
1713- }
1734+ if (func && param_num < func -> num_params ) {
1735+ var_t * target = & func -> param_defs [param_num ];
1736+ if (!target -> ptr_level && !target -> array_size )
1737+ param =
1738+ scalarize_array_literal (parent , bb , param , target -> type );
17141739 }
17151740 /* Handle parameter type conversion for direct calls.
17161741 * Indirect calls currently don't provide function instance.
17171742 */
1718- if (func ) {
1719- if (param_num >= func -> num_params && func -> va_args ) {
1743+ if (func && param_num >= func -> num_params && func -> va_args ) {
1744+ /* Default promotions apply to scalar varargs, but pointer-like
1745+ * values (including array literals) must flow through unchanged so
1746+ * "%p" and friends see an address rather than a scalarized value.
1747+ */
1748+ if (!is_pointer_like_value (param ))
17201749 param = promote (parent , bb , param , TY_int , 0 );
1721- } else {
1722- param =
1723- resize_var (parent , bb , param , & func -> param_defs [param_num ]);
1724- }
1750+ } else if (func ) {
1751+ param = resize_var (parent , bb , param , & func -> param_defs [param_num ]);
17251752 }
17261753
17271754 params [param_num ++ ] = param ;
@@ -2148,6 +2175,7 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
21482175 var_t * compound_var =
21492176 require_typed_var (parent , cast_or_literal_type );
21502177 gen_name_to (compound_var -> var_name );
2178+ compound_var -> is_compound_literal = true;
21512179
21522180 /* Check if this is an array compound literal (int[]){...} */
21532181 bool is_array_literal = (cast_ptr_level == -1 );
@@ -2159,7 +2187,7 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
21592187 compound_var -> array_size = 0 ;
21602188 add_insn (parent , * bb , OP_allocat , compound_var , NULL , NULL , 0 ,
21612189 NULL );
2162- parse_array_compound_literal (compound_var , parent , bb , true );
2190+ parse_array_compound_literal (compound_var , parent , bb );
21632191
21642192 if (compound_var -> array_size == 0 ) {
21652193 compound_var -> init_val = 0 ;
@@ -3628,13 +3656,22 @@ void read_ternary_operation(block_t *parent, basic_block_t **bb)
36283656 bool true_ptr_like = is_pointer_like_value (true_val );
36293657 bool false_ptr_like = is_pointer_like_value (false_val );
36303658
3631- if (true_array && !false_ptr_like )
3632- true_val = scalarize_array_literal (parent , & then_ , true_val ,
3633- false_val ? false_val -> type : NULL );
3659+ /* The ternary result must look like whichever side is pointer-like. If the
3660+ * "true" expression is still a raw array literal but the "false" side is a
3661+ * plain scalar, materialize the literal now so both branches produce
3662+ * comparable scalar SSA values.
3663+ */
3664+ true_val = scalarize_array_literal_if_needed (
3665+ parent , & then_ , true_val , false_val ? false_val -> type : NULL ,
3666+ true_array && !false_ptr_like );
36343667
3635- if (false_array && !true_ptr_like )
3636- false_val = scalarize_array_literal (parent , & else_ , false_val ,
3637- true_val ? true_val -> type : NULL );
3668+ /* Apply the same conversion symmetrically when only the false branch is a
3669+ * literal array. This prevents OP_assign from trying to move array storage
3670+ * into a scalar destination later in code generation.
3671+ */
3672+ false_val = scalarize_array_literal_if_needed (
3673+ parent , & else_ , false_val , true_val ? true_val -> type : NULL ,
3674+ false_array && !true_ptr_like );
36383675
36393676 vd = require_var (parent );
36403677 gen_name_to (vd -> var_name );
@@ -3801,9 +3838,9 @@ bool read_body_assignment(char *token,
38013838 read_expr (parent , bb );
38023839
38033840 var_t * rhs_val = opstack_pop ();
3804- if (! lvalue . ptr_level && ! lvalue . is_reference )
3805- rhs_val = scalarize_array_literal ( parent , bb , rhs_val ,
3806- lvalue .type );
3841+ rhs_val = scalarize_array_literal_if_needed (
3842+ parent , bb , rhs_val , lvalue . type ,
3843+ ! lvalue . ptr_level && ! lvalue .is_reference );
38073844 opstack_push (rhs_val );
38083845 vd = require_var (parent );
38093846 vd -> init_val = increment_size ;
@@ -4546,9 +4583,9 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
45464583 read_ternary_operation (parent , & bb );
45474584
45484585 var_t * rhs = opstack_pop ();
4549- if (! var -> ptr_level && var -> array_size == 0 )
4550- rhs = scalarize_array_literal ( parent , & bb , rhs ,
4551- var -> type );
4586+ rhs = scalarize_array_literal_if_needed (
4587+ parent , & bb , rhs , var -> type ,
4588+ ! var -> ptr_level && var -> array_size == 0 );
45524589
45534590 rs1 = resize_var (parent , & bb , rhs , var );
45544591 add_insn (parent , bb , OP_assign , var , rs1 , NULL , 0 , NULL );
@@ -4643,9 +4680,9 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
46434680 read_expr (parent , & bb );
46444681 read_ternary_operation (parent , & bb );
46454682 var_t * rhs = opstack_pop ();
4646- if (! nv -> ptr_level && nv -> array_size == 0 )
4647- rhs = scalarize_array_literal ( parent , & bb , rhs ,
4648- nv -> type );
4683+ rhs = scalarize_array_literal_if_needed (
4684+ parent , & bb , rhs , nv -> type ,
4685+ ! nv -> ptr_level && nv -> array_size == 0 );
46494686
46504687 rs1 = resize_var (parent , & bb , rhs , nv );
46514688 add_insn (parent , bb , OP_assign , nv , rs1 , NULL , 0 , NULL );
@@ -5303,6 +5340,7 @@ void initialize_struct_field(var_t *nv, var_t *v, int offset)
53035340 nv -> base = NULL ;
53045341 nv -> subscript = 0 ;
53055342 nv -> subscripts_idx = 0 ;
5343+ nv -> is_compound_literal = false;
53065344}
53075345
53085346void read_global_statement (void )
0 commit comments