@@ -46,9 +46,9 @@ void parse_array_init(var_t *var,
4646 basic_block_t * * bb ,
4747 bool emit_code );
4848void parse_array_compound_literal (var_t * var ,
49- block_t * parent ,
50- basic_block_t * * bb ,
51- bool emit_code );
49+ block_t * parent ,
50+ basic_block_t * * bb ,
51+ bool emit_code );
5252
5353label_t * find_label (char * name )
5454{
@@ -1287,9 +1287,9 @@ void parse_array_init(var_t *var,
12871287}
12881288
12891289void parse_array_compound_literal (var_t * var ,
1290- block_t * parent ,
1291- basic_block_t * * bb ,
1292- bool emit_code )
1290+ block_t * parent ,
1291+ basic_block_t * * bb ,
1292+ bool emit_code )
12931293{
12941294 int elem_size = var -> type -> size ;
12951295 int count = 0 ;
@@ -1307,8 +1307,8 @@ void parse_array_compound_literal(var_t *var,
13071307 target .type = var -> type ;
13081308 target .ptr_level = 0 ;
13091309 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 );
1310+ var_t * elem_addr =
1311+ compute_element_address ( parent , bb , var , count , elem_size );
13121312 add_insn (parent , * bb , OP_write , NULL , elem_addr , store_val ,
13131313 elem_size , NULL );
13141314 }
@@ -1322,6 +1322,35 @@ void parse_array_compound_literal(var_t *var,
13221322 lex_expect (T_close_curly );
13231323 var -> array_size = count ;
13241324}
1325+ static bool is_array_literal_temp (var_t * var )
1326+ {
1327+ return var && var -> array_size > 0 && var -> var_name [0 ] == '.' ;
1328+ }
1329+
1330+ static var_t * scalarize_array_literal (block_t * parent ,
1331+ basic_block_t * * bb ,
1332+ var_t * array_var ,
1333+ type_t * hint_type )
1334+ {
1335+ if (!is_array_literal_temp (array_var ))
1336+ return array_var ;
1337+
1338+ type_t * elem_type = hint_type ? hint_type : array_var -> type ;
1339+ if (!elem_type )
1340+ elem_type = TY_int ;
1341+
1342+ int elem_size = elem_type -> size ;
1343+ if (elem_size <= 0 )
1344+ elem_size = TY_int -> size ;
1345+
1346+ var_t * scalar = require_typed_var (parent , elem_type );
1347+ scalar -> ptr_level = 0 ;
1348+ gen_name_to (scalar -> var_name );
1349+ scalar -> init_val = array_var -> init_val ;
1350+
1351+ add_insn (parent , * bb , OP_read , scalar , array_var , NULL , elem_size , NULL );
1352+ return scalar ;
1353+ }
13251354void read_inner_var_decl (var_t * vd , bool anon , bool is_param )
13261355{
13271356 /* Preserve typedef pointer level - don't reset if already inherited */
@@ -1614,7 +1643,16 @@ void read_func_parameters(func_t *func, block_t *parent, basic_block_t **bb)
16141643 read_ternary_operation (parent , bb );
16151644
16161645 param = opstack_pop ();
1617-
1646+ if (func ) {
1647+ if (param_num < func -> num_params ) {
1648+ var_t * target = & func -> param_defs [param_num ];
1649+ if (!target -> ptr_level && !target -> array_size )
1650+ param = scalarize_array_literal (parent , bb , param ,
1651+ target -> type );
1652+ } else if (func -> va_args ) {
1653+ param = scalarize_array_literal (parent , bb , param , TY_int );
1654+ }
1655+ }
16181656 /* Handle parameter type conversion for direct calls.
16191657 * Indirect calls currently don't provide function instance.
16201658 */
@@ -2857,6 +2895,16 @@ void read_expr(block_t *parent, basic_block_t **bb)
28572895 continue ; /* skip normal processing */
28582896 }
28592897
2898+ bool rs1_is_ptr_like = rs1 && (rs1 -> ptr_level || rs1 -> array_size );
2899+ bool rs2_is_ptr_like = rs2 && (rs2 -> ptr_level || rs2 -> array_size );
2900+
2901+ if (is_array_literal_temp (rs1 ) && !rs2_is_ptr_like )
2902+ rs1 = scalarize_array_literal (parent , bb , rs1 ,
2903+ rs2 && rs2 -> type ? rs2 -> type : NULL );
2904+
2905+ if (is_array_literal_temp (rs2 ) && !rs1_is_ptr_like )
2906+ rs2 = scalarize_array_literal (parent , bb , rs2 ,
2907+ rs1 && rs1 -> type ? rs1 -> type : NULL );
28602908 /* Constant folding for binary operations */
28612909 if (rs1 && rs2 && rs1 -> init_val && !rs1 -> ptr_level && !rs1 -> is_global &&
28622910 rs2 -> init_val && !rs2 -> ptr_level && !rs2 -> is_global ) {
@@ -3477,7 +3525,7 @@ void finalize_logical(opcode_t op,
34773525
34783526void read_ternary_operation (block_t * parent , basic_block_t * * bb )
34793527{
3480- var_t * vd , * rs1 ;
3528+ var_t * vd ;
34813529
34823530 if (!lex_accept (T_question ))
34833531 return ;
@@ -3502,17 +3550,39 @@ void read_ternary_operation(block_t *parent, basic_block_t **bb)
35023550 abort ();
35033551 }
35043552
3505- rs1 = opstack_pop ();
3506- vd = require_var (parent );
3507- gen_name_to (vd -> var_name );
3508- add_insn (parent , then_ , OP_assign , vd , rs1 , NULL , 0 , NULL );
3553+ var_t * true_val = opstack_pop ();
35093554
35103555 /* false branch */
35113556 read_expr (parent , & else_ );
35123557 bb_connect (* bb , else_ , ELSE );
3558+ var_t * false_val = opstack_pop ();
3559+ bool true_array = is_array_literal_temp (true_val );
3560+ bool false_array = is_array_literal_temp (false_val );
35133561
3514- rs1 = opstack_pop ();
3515- add_insn (parent , else_ , OP_assign , vd , rs1 , NULL , 0 , NULL );
3562+ if (true_array && !false_array )
3563+ true_val = scalarize_array_literal (parent , & then_ , true_val ,
3564+ false_val ? false_val -> type : NULL );
3565+
3566+ if (false_array && !true_array )
3567+ false_val = scalarize_array_literal (parent , & else_ , false_val ,
3568+ true_val ? true_val -> type : NULL );
3569+
3570+ vd = require_var (parent );
3571+ gen_name_to (vd -> var_name );
3572+ add_insn (parent , then_ , OP_assign , vd , true_val , NULL , 0 , NULL );
3573+ add_insn (parent , else_ , OP_assign , vd , false_val , NULL , 0 , NULL );
3574+
3575+ var_t * array_ref = NULL ;
3576+ if (is_array_literal_temp (true_val ))
3577+ array_ref = true_val ;
3578+ else if (is_array_literal_temp (false_val ))
3579+ array_ref = false_val ;
3580+
3581+ if (array_ref ) {
3582+ vd -> array_size = array_ref -> array_size ;
3583+ vd -> init_val = array_ref -> init_val ;
3584+ vd -> type = array_ref -> type ;
3585+ }
35163586
35173587 vd -> is_ternary_ret = true;
35183588 opstack_push (vd );
@@ -3661,6 +3731,11 @@ bool read_body_assignment(char *token,
36613731
36623732 read_expr (parent , bb );
36633733
3734+ var_t * rhs_val = opstack_pop ();
3735+ if (!lvalue .ptr_level && !lvalue .is_reference )
3736+ rhs_val = scalarize_array_literal (parent , bb , rhs_val ,
3737+ lvalue .type );
3738+ opstack_push (rhs_val );
36643739 vd = require_var (parent );
36653740 vd -> init_val = increment_size ;
36663741 gen_name_to (vd -> var_name );
@@ -4403,27 +4478,12 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
44034478
44044479 var_t * expr_result = opstack_pop ();
44054480
4406- /* Handle array compound literal to scalar assignment.
4407- * When assigning array compound literals to scalar
4408- * variables, use the first element value rather than array
4409- * address.
4410- */
4411- if (expr_result && expr_result -> array_size > 0 &&
4412- !var -> ptr_level && var -> array_size == 0 && var -> type &&
4413- (var -> type -> base_type == TYPE_int ||
4414- var -> type -> base_type == TYPE_short ) &&
4415- expr_result -> var_name [0 ] == '.' ) {
4416- var_t * first_elem = require_var (parent );
4417- first_elem -> type = var -> type ;
4418- gen_name_to (first_elem -> var_name );
4419-
4420- /* Extract first element from compound literal array */
4421- add_insn (parent , bb , OP_read , first_elem , expr_result ,
4422- NULL , var -> type -> size , NULL );
4423- expr_result = first_elem ;
4424- }
4481+ var_t * rhs = expr_result ;
4482+ if (!var -> ptr_level && var -> array_size == 0 )
4483+ rhs =
4484+ scalarize_array_literal (parent , bb , rhs , var -> type );
44254485
4426- rs1 = resize_var (parent , & bb , expr_result , var );
4486+ rs1 = resize_var (parent , & bb , rhs , var );
44274487 add_insn (parent , bb , OP_assign , var , rs1 , NULL , 0 , NULL );
44284488 }
44294489 }
@@ -4515,8 +4575,13 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
45154575 } else {
45164576 read_expr (parent , & bb );
45174577 read_ternary_operation (parent , & bb );
4578+ var_t * expr_result = opstack_pop ();
4579+ var_t * rhs = expr_result ;
4580+ if (!nv -> ptr_level && nv -> array_size == 0 )
4581+ rhs = scalarize_array_literal (parent , bb , rhs ,
4582+ nv -> type );
45184583
4519- rs1 = resize_var (parent , & bb , opstack_pop () , nv );
4584+ rs1 = resize_var (parent , & bb , rhs , nv );
45204585 add_insn (parent , bb , OP_assign , nv , rs1 , NULL , 0 , NULL );
45214586 }
45224587 }
0 commit comments