@@ -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+ */
12891292void 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 */
13301336bool 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}
13601366void 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
35323548void 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