@@ -122,11 +122,11 @@ int write_symbol(char *data)
122122 return start_len ;
123123}
124124
125- int get_size (var_t * var , type_t * type )
125+ int get_size (var_t * var )
126126{
127127 if (var -> is_ptr || var -> is_func )
128128 return PTR_SIZE ;
129- return type -> size ;
129+ return var -> type -> size ;
130130}
131131
132132int get_operator_prio (opcode_t op )
@@ -222,24 +222,74 @@ opcode_t get_operator()
222222 return op ;
223223}
224224
225- var_t * promote (block_t * block , basic_block_t * * bb , var_t * var )
225+ /**
226+ *
227+ */
228+ var_t * promote_unchecked (block_t * block ,
229+ basic_block_t * * bb ,
230+ var_t * var ,
231+ type_t * target_type ,
232+ int target_ptr )
233+ {
234+ var_t * rd = require_typed_ptr_var (block , target_type , target_ptr );
235+ gen_name_to (rd -> var_name );
236+ add_insn (block , * bb , OP_sign_ext , rd , var , NULL , target_type -> size , NULL );
237+ return rd ;
238+ }
239+
240+ var_t * promote (block_t * block ,
241+ basic_block_t * * bb ,
242+ var_t * var ,
243+ type_t * target_type ,
244+ int target_ptr )
226245{
227246 /* Effectively checking whether var has size of int */
228- if (var -> type -> size == 4 || var -> is_ptr || var -> array_size != 0 )
247+ if (var -> type -> size == target_type -> size || var -> is_ptr || var -> array_size )
229248 return var ;
230249
231- if (var -> type -> size > 4 && !var -> is_ptr ) {
250+ if (var -> type -> size > TY_int -> size && !var -> is_ptr ) {
232251 printf ("Warning: Suspicious type promotion %s\n" , var -> type -> type_name );
233252 return var ;
234253 }
235254
236- var_t * rd = require_var (block );
237- gen_name_to (rd -> var_name );
238- add_insn (block , * bb , OP_sign_ext , rd , var , NULL , 4 , NULL );
255+ return promote_unchecked (block , bb , var , target_type , target_ptr );
256+ }
239257
258+ var_t * truncate_unchecked (block_t * block ,
259+ basic_block_t * * bb ,
260+ var_t * var ,
261+ type_t * target_type ,
262+ int target_ptr )
263+ {
264+ var_t * rd = require_typed_ptr_var (block , target_type , target_ptr );
265+ gen_name_to (rd -> var_name );
266+ add_insn (block , * bb , OP_trunc , rd , var , NULL , target_type -> size , NULL );
240267 return rd ;
241268}
242269
270+ var_t * resize_var (block_t * block , basic_block_t * * bb , var_t * from , var_t * to )
271+ {
272+ bool is_from_ptr = from -> is_ptr || from -> array_size ,
273+ is_to_ptr = to -> is_ptr || to -> array_size ;
274+
275+ if (is_from_ptr && is_to_ptr )
276+ return from ;
277+
278+ int from_size = get_size (from ), to_size = get_size (to );
279+
280+ if (from_size > to_size ) {
281+ /* Truncation */
282+ return truncate_unchecked (block , bb , from , to -> type , to -> is_ptr );
283+ }
284+
285+ if (from_size < to_size ) {
286+ /* Sign extend */
287+ return promote_unchecked (block , bb , from , to -> type , to -> is_ptr );
288+ }
289+
290+ return from ;
291+ }
292+
243293int read_numeric_constant (char buffer [])
244294{
245295 int i = 0 ;
@@ -655,8 +705,7 @@ void read_full_var_decl(var_t *vd, int anon, int is_param)
655705{
656706 char type_name [MAX_TYPE_LEN ];
657707 int find_type_flag = lex_accept (T_struct ) ? 2 : 1 ;
658- lex_ident (T_identifier , vd -> type_name );
659- strcpy (type_name , vd -> type_name );
708+ lex_ident (T_identifier , type_name );
660709 type_t * type = find_type (type_name , find_type_flag );
661710
662711 if (!type ) {
@@ -672,7 +721,6 @@ void read_full_var_decl(var_t *vd, int anon, int is_param)
672721/* starting next_token, need to check the type */
673722void read_partial_var_decl (var_t * vd , var_t * template )
674723{
675- strcpy (vd -> type_name , template -> type_name );
676724 read_inner_var_decl (vd , 0 , 0 );
677725}
678726
@@ -790,8 +838,13 @@ void read_func_parameters(func_t *func, block_t *parent, basic_block_t **bb)
790838
791839 param = opstack_pop ();
792840
793- if (func && param_num >= func -> num_params && func -> va_args ) {
794- param = promote (parent , bb , param );
841+ if (func ) {
842+ if (param_num >= func -> num_params && func -> va_args ) {
843+ param = promote (parent , bb , param , TY_int , 0 );
844+ } else {
845+ param =
846+ resize_var (parent , bb , param , & func -> param_defs [param_num ]);
847+ }
795848 }
796849
797850 params [param_num ++ ] = param ;
@@ -1269,8 +1322,8 @@ void read_lvalue(lvalue_t *lvalue,
12691322 /* already peeked and have the variable */
12701323 lex_expect (T_identifier );
12711324
1272- lvalue -> type = find_type ( var -> type_name , 0 ) ;
1273- lvalue -> size = get_size (var , lvalue -> type );
1325+ lvalue -> type = var -> type ;
1326+ lvalue -> size = get_size (var );
12741327 lvalue -> is_ptr = var -> is_ptr ;
12751328 lvalue -> is_func = var -> is_func ;
12761329 lvalue -> is_reference = false;
@@ -1368,10 +1421,10 @@ void read_lvalue(lvalue_t *lvalue,
13681421
13691422 /* change type currently pointed to */
13701423 var = find_member (token , lvalue -> type );
1371- lvalue -> type = find_type ( var -> type_name , 0 ) ;
1424+ lvalue -> type = var -> type ;
13721425 lvalue -> is_ptr = var -> is_ptr ;
13731426 lvalue -> is_func = var -> is_func ;
1374- lvalue -> size = get_size (var , lvalue -> type );
1427+ lvalue -> size = get_size (var );
13751428
13761429 /* if it is an array, get the address of first element instead of
13771430 * its value.
@@ -1829,6 +1882,7 @@ bool read_body_assignment(char *token,
18291882 if (lvalue .is_reference ) {
18301883 add_insn (parent , * bb , OP_write , NULL , t , vd , size , NULL );
18311884 } else {
1885+ vd = resize_var (parent , bb , vd , t );
18321886 add_insn (parent , * bb , OP_assign , t , vd , NULL , 0 , NULL );
18331887 }
18341888 } else {
@@ -1868,14 +1922,7 @@ bool read_body_assignment(char *token,
18681922 add_insn (parent , * bb , OP_write , NULL , t , vd , lvalue .size ,
18691923 NULL );
18701924 } else {
1871- if (lvalue .type -> size < vd -> type -> size ) {
1872- rs1 = require_typed_var (parent , TY_char );
1873- gen_name_to (rs1 -> var_name );
1874- add_insn (parent , * bb , OP_trunc , rs1 , vd , NULL ,
1875- lvalue .size , NULL );
1876- vd = rs1 ;
1877- }
1878-
1925+ vd = resize_var (parent , bb , vd , t );
18791926 add_insn (parent , * bb , OP_assign , t , vd , NULL , 0 , NULL );
18801927 }
18811928 }
@@ -1894,6 +1941,7 @@ bool read_body_assignment(char *token,
18941941 } else {
18951942 rs1 = opstack_pop ();
18961943 vd = opstack_pop ();
1944+ rs1 = resize_var (parent , bb , rs1 , vd );
18971945 add_insn (parent , * bb , OP_assign , vd , rs1 , NULL , 0 , NULL );
18981946 }
18991947 }
@@ -2447,15 +2495,15 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
24472495 int find_type_flag = lex_accept (T_struct ) ? 2 : 1 ;
24482496 type = find_type (token , find_type_flag );
24492497 if (type ) {
2450- var = require_var (blk );
2498+ var = require_typed_var (blk , type );
24512499 read_full_var_decl (var , 0 , 0 );
24522500 add_insn (blk , setup , OP_allocat , var , NULL , NULL , 0 , NULL );
24532501 add_symbol (setup , var );
24542502 if (lex_accept (T_assign )) {
24552503 read_expr (blk , & setup );
24562504 read_ternary_operation (blk , & setup );
24572505
2458- rs1 = opstack_pop ();
2506+ rs1 = resize_var ( parent , & bb , opstack_pop (), var );
24592507 add_insn (blk , setup , OP_assign , var , rs1 , NULL , 0 , NULL );
24602508 }
24612509 while (lex_accept (T_comma )) {
@@ -2465,14 +2513,14 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
24652513 perform_side_effect (blk , setup );
24662514
24672515 /* multiple (partial) declarations */
2468- nv = require_var (blk );
2516+ nv = require_typed_var (blk , type );
24692517 read_partial_var_decl (nv , var ); /* partial */
24702518 add_insn (blk , setup , OP_allocat , nv , NULL , NULL , 0 , NULL );
24712519 add_symbol (setup , nv );
24722520 if (lex_accept (T_assign )) {
24732521 read_expr (blk , & setup );
24742522
2475- rs1 = opstack_pop ();
2523+ rs1 = resize_var ( parent , & bb , opstack_pop (), nv );
24762524 add_insn (blk , setup , OP_assign , nv , rs1 , NULL , 0 , NULL );
24772525 }
24782526 }
@@ -2604,7 +2652,7 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
26042652 read_expr (parent , & bb );
26052653 read_ternary_operation (parent , & bb );
26062654
2607- rs1 = opstack_pop ();
2655+ rs1 = resize_var ( parent , & bb , opstack_pop (), var );
26082656 add_insn (parent , bb , OP_assign , var , rs1 , NULL , 0 , NULL );
26092657 }
26102658 while (lex_accept (T_comma )) {
@@ -2621,7 +2669,7 @@ basic_block_t *read_body_statement(block_t *parent, basic_block_t *bb)
26212669 if (lex_accept (T_assign )) {
26222670 read_expr (parent , & bb );
26232671
2624- rs1 = opstack_pop ();
2672+ rs1 = resize_var ( parent , & bb , opstack_pop (), nv );
26252673 add_insn (parent , bb , OP_assign , nv , rs1 , NULL , 0 , NULL );
26262674 }
26272675 }
0 commit comments