@@ -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{
@@ -1334,9 +1334,9 @@ void parse_array_init(var_t *var,
13341334}
13351335
13361336void parse_array_compound_literal (var_t * var ,
1337- block_t * parent ,
1338- basic_block_t * * bb ,
1339- bool emit_code )
1337+ block_t * parent ,
1338+ basic_block_t * * bb ,
1339+ bool emit_code )
13401340{
13411341 int elem_size = var -> type -> size ;
13421342 int count = 0 ;
@@ -1354,8 +1354,8 @@ void parse_array_compound_literal(var_t *var,
13541354 target .type = var -> type ;
13551355 target .ptr_level = 0 ;
13561356 var_t * store_val = resize_var (parent , bb , value , & target );
1357- var_t * elem_addr = compute_element_address (
1358- parent , bb , var , count , elem_size );
1357+ var_t * elem_addr =
1358+ compute_element_address ( parent , bb , var , count , elem_size );
13591359 add_insn (parent , * bb , OP_write , NULL , elem_addr , store_val ,
13601360 elem_size , NULL );
13611361 }
@@ -1369,6 +1369,35 @@ void parse_array_compound_literal(var_t *var,
13691369 lex_expect (T_close_curly );
13701370 var -> array_size = count ;
13711371}
1372+ static bool is_array_literal_temp (var_t * var )
1373+ {
1374+ return var && var -> array_size > 0 && var -> var_name [0 ] == '.' ;
1375+ }
1376+
1377+ static var_t * scalarize_array_literal (block_t * parent ,
1378+ basic_block_t * * bb ,
1379+ var_t * array_var ,
1380+ type_t * hint_type )
1381+ {
1382+ if (!is_array_literal_temp (array_var ))
1383+ return array_var ;
1384+
1385+ type_t * elem_type = hint_type ? hint_type : array_var -> type ;
1386+ if (!elem_type )
1387+ elem_type = TY_int ;
1388+
1389+ int elem_size = elem_type -> size ;
1390+ if (elem_size <= 0 )
1391+ elem_size = TY_int -> size ;
1392+
1393+ var_t * scalar = require_typed_var (parent , elem_type );
1394+ scalar -> ptr_level = 0 ;
1395+ gen_name_to (scalar -> var_name );
1396+ scalar -> init_val = array_var -> init_val ;
1397+
1398+ add_insn (parent , * bb , OP_read , scalar , array_var , NULL , elem_size , NULL );
1399+ return scalar ;
1400+ }
13721401void read_inner_var_decl (var_t * vd , bool anon , bool is_param )
13731402{
13741403 /* Preserve typedef pointer level - don't reset if already inherited */
@@ -1661,7 +1690,16 @@ void read_func_parameters(func_t *func, block_t *parent, basic_block_t **bb)
16611690 read_ternary_operation (parent , bb );
16621691
16631692 param = opstack_pop ();
1664-
1693+ if (func ) {
1694+ if (param_num < func -> num_params ) {
1695+ var_t * target = & func -> param_defs [param_num ];
1696+ if (!target -> ptr_level && !target -> array_size )
1697+ param = scalarize_array_literal (parent , bb , param ,
1698+ target -> type );
1699+ } else if (func -> va_args ) {
1700+ param = scalarize_array_literal (parent , bb , param , TY_int );
1701+ }
1702+ }
16651703 /* Handle parameter type conversion for direct calls.
16661704 * Indirect calls currently don't provide function instance.
16671705 */
@@ -2904,6 +2942,16 @@ void read_expr(block_t *parent, basic_block_t **bb)
29042942 continue ; /* skip normal processing */
29052943 }
29062944
2945+ bool rs1_is_ptr_like = rs1 && (rs1 -> ptr_level || rs1 -> array_size );
2946+ bool rs2_is_ptr_like = rs2 && (rs2 -> ptr_level || rs2 -> array_size );
2947+
2948+ if (is_array_literal_temp (rs1 ) && !rs2_is_ptr_like )
2949+ rs1 = scalarize_array_literal (parent , bb , rs1 ,
2950+ rs2 && rs2 -> type ? rs2 -> type : NULL );
2951+
2952+ if (is_array_literal_temp (rs2 ) && !rs1_is_ptr_like )
2953+ rs2 = scalarize_array_literal (parent , bb , rs2 ,
2954+ rs1 && rs1 -> type ? rs1 -> type : NULL );
29072955 /* Constant folding for binary operations */
29082956 if (rs1 && rs2 && rs1 -> init_val && !rs1 -> ptr_level && !rs1 -> is_global &&
29092957 rs2 -> init_val && !rs2 -> ptr_level && !rs2 -> is_global ) {
@@ -3524,7 +3572,7 @@ void finalize_logical(opcode_t op,
35243572
35253573void read_ternary_operation (block_t * parent , basic_block_t * * bb )
35263574{
3527- var_t * vd , * rs1 ;
3575+ var_t * vd ;
35283576
35293577 if (!lex_accept (T_question ))
35303578 return ;
@@ -3549,17 +3597,39 @@ void read_ternary_operation(block_t *parent, basic_block_t **bb)
35493597 abort ();
35503598 }
35513599
3552- rs1 = opstack_pop ();
3553- vd = require_var (parent );
3554- gen_name_to (vd -> var_name );
3555- add_insn (parent , then_ , OP_assign , vd , rs1 , NULL , 0 , NULL );
3600+ var_t * true_val = opstack_pop ();
35563601
35573602 /* false branch */
35583603 read_expr (parent , & else_ );
35593604 bb_connect (* bb , else_ , ELSE );
3605+ var_t * false_val = opstack_pop ();
3606+ bool true_array = is_array_literal_temp (true_val );
3607+ bool false_array = is_array_literal_temp (false_val );
35603608
3561- rs1 = opstack_pop ();
3562- add_insn (parent , else_ , OP_assign , vd , rs1 , NULL , 0 , NULL );
3609+ if (true_array && !false_array )
3610+ true_val = scalarize_array_literal (parent , & then_ , true_val ,
3611+ false_val ? false_val -> type : NULL );
3612+
3613+ if (false_array && !true_array )
3614+ false_val = scalarize_array_literal (parent , & else_ , false_val ,
3615+ true_val ? true_val -> type : NULL );
3616+
3617+ vd = require_var (parent );
3618+ gen_name_to (vd -> var_name );
3619+ add_insn (parent , then_ , OP_assign , vd , true_val , NULL , 0 , NULL );
3620+ add_insn (parent , else_ , OP_assign , vd , false_val , NULL , 0 , NULL );
3621+
3622+ var_t * array_ref = NULL ;
3623+ if (is_array_literal_temp (true_val ))
3624+ array_ref = true_val ;
3625+ else if (is_array_literal_temp (false_val ))
3626+ array_ref = false_val ;
3627+
3628+ if (array_ref ) {
3629+ vd -> array_size = array_ref -> array_size ;
3630+ vd -> init_val = array_ref -> init_val ;
3631+ vd -> type = array_ref -> type ;
3632+ }
35633633
35643634 vd -> is_ternary_ret = true;
35653635 opstack_push (vd );
@@ -3708,6 +3778,11 @@ bool read_body_assignment(char *token,
37083778
37093779 read_expr (parent , bb );
37103780
3781+ var_t * rhs_val = opstack_pop ();
3782+ if (!lvalue .ptr_level && !lvalue .is_reference )
3783+ rhs_val = scalarize_array_literal (parent , bb , rhs_val ,
3784+ lvalue .type );
3785+ opstack_push (rhs_val );
37113786 vd = require_var (parent );
37123787 vd -> init_val = increment_size ;
37133788 gen_name_to (vd -> var_name );
@@ -4450,27 +4525,12 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
44504525
44514526 var_t * expr_result = opstack_pop ();
44524527
4453- /* Handle array compound literal to scalar assignment.
4454- * When assigning array compound literals to scalar
4455- * variables, use the first element value rather than array
4456- * address.
4457- */
4458- if (expr_result && expr_result -> array_size > 0 &&
4459- !var -> ptr_level && var -> array_size == 0 && var -> type &&
4460- (var -> type -> base_type == TYPE_int ||
4461- var -> type -> base_type == TYPE_short ) &&
4462- expr_result -> var_name [0 ] == '.' ) {
4463- var_t * first_elem = require_var (parent );
4464- first_elem -> type = var -> type ;
4465- gen_name_to (first_elem -> var_name );
4466-
4467- /* Extract first element from compound literal array */
4468- add_insn (parent , bb , OP_read , first_elem , expr_result ,
4469- NULL , var -> type -> size , NULL );
4470- expr_result = first_elem ;
4471- }
4528+ var_t * rhs = expr_result ;
4529+ if (!var -> ptr_level && var -> array_size == 0 )
4530+ rhs =
4531+ scalarize_array_literal (parent , bb , rhs , var -> type );
44724532
4473- rs1 = resize_var (parent , & bb , expr_result , var );
4533+ rs1 = resize_var (parent , & bb , rhs , var );
44744534 add_insn (parent , bb , OP_assign , var , rs1 , NULL , 0 , NULL );
44754535 }
44764536 }
@@ -4562,8 +4622,13 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
45624622 } else {
45634623 read_expr (parent , & bb );
45644624 read_ternary_operation (parent , & bb );
4625+ var_t * expr_result = opstack_pop ();
4626+ var_t * rhs = expr_result ;
4627+ if (!nv -> ptr_level && nv -> array_size == 0 )
4628+ rhs = scalarize_array_literal (parent , bb , rhs ,
4629+ nv -> type );
45654630
4566- rs1 = resize_var (parent , & bb , opstack_pop () , nv );
4631+ rs1 = resize_var (parent , & bb , rhs , nv );
45674632 add_insn (parent , bb , OP_assign , nv , rs1 , NULL , 0 , NULL );
45684633 }
45694634 }
0 commit comments