@@ -281,7 +281,8 @@ var_t *truncate_unchecked(block_t *block,
281
281
var_t * resize_var (block_t * block , basic_block_t * * bb , var_t * from , var_t * to )
282
282
{
283
283
bool is_from_ptr = from -> ptr_level || from -> array_size ,
284
- is_to_ptr = to -> ptr_level || to -> array_size ;
284
+ is_to_ptr = to -> ptr_level || to -> array_size ||
285
+ (to -> type && to -> type -> ptr_level > 0 );
285
286
286
287
if (is_from_ptr && is_to_ptr )
287
288
return from ;
@@ -1291,10 +1292,6 @@ void read_full_var_decl(var_t *vd, bool anon, bool is_param)
1291
1292
1292
1293
vd -> type = type ;
1293
1294
1294
- /* Inherit pointer level from typedef */
1295
- if (type -> ptr_level > 0 )
1296
- vd -> ptr_level = type -> ptr_level ;
1297
-
1298
1295
read_inner_var_decl (vd , anon , is_param );
1299
1296
}
1300
1297
@@ -1569,8 +1566,28 @@ void handle_single_dereference(block_t *parent, basic_block_t **bb)
1569
1566
vd = require_deref_var (parent , var -> type , var -> ptr_level );
1570
1567
if (lvalue .ptr_level > 1 )
1571
1568
sz = PTR_SIZE ;
1572
- else
1573
- sz = lvalue .type -> size ;
1569
+ else {
1570
+ /* For typedef pointers, get the size of the pointed-to type */
1571
+ if (lvalue .type && lvalue .type -> ptr_level > 0 ) {
1572
+ /* This is a typedef pointer */
1573
+ switch (lvalue .type -> base_type ) {
1574
+ case TYPE_char :
1575
+ sz = TY_char -> size ;
1576
+ break ;
1577
+ case TYPE_int :
1578
+ sz = TY_int -> size ;
1579
+ break ;
1580
+ case TYPE_void :
1581
+ sz = 1 ;
1582
+ break ;
1583
+ default :
1584
+ sz = lvalue .type -> size ;
1585
+ break ;
1586
+ }
1587
+ } else {
1588
+ sz = lvalue .type -> size ;
1589
+ }
1590
+ }
1574
1591
gen_name_to (vd -> var_name );
1575
1592
opstack_push (vd );
1576
1593
add_insn (parent , * bb , OP_read , vd , rs1 , NULL , sz , NULL );
@@ -1628,8 +1645,29 @@ void handle_multiple_dereference(block_t *parent, basic_block_t **bb)
1628
1645
lvalue .ptr_level > i ? lvalue .ptr_level - i - 1 : 0 );
1629
1646
if (lvalue .ptr_level > i + 1 )
1630
1647
sz = PTR_SIZE ;
1631
- else
1632
- sz = lvalue .type -> size ;
1648
+ else {
1649
+ /* For typedef pointers, get the size of the pointed-to type */
1650
+ if (lvalue .type && lvalue .type -> ptr_level > 0 &&
1651
+ i == deref_count - 1 ) {
1652
+ /* This is a typedef pointer on the final dereference */
1653
+ switch (lvalue .type -> base_type ) {
1654
+ case TYPE_char :
1655
+ sz = TY_char -> size ;
1656
+ break ;
1657
+ case TYPE_int :
1658
+ sz = TY_int -> size ;
1659
+ break ;
1660
+ case TYPE_void :
1661
+ sz = 1 ;
1662
+ break ;
1663
+ default :
1664
+ sz = lvalue .type -> size ;
1665
+ break ;
1666
+ }
1667
+ } else {
1668
+ sz = lvalue .type -> size ;
1669
+ }
1670
+ }
1633
1671
gen_name_to (vd -> var_name );
1634
1672
opstack_push (vd );
1635
1673
add_insn (parent , * bb , OP_read , vd , rs1 , NULL , sz , NULL );
@@ -2197,6 +2235,99 @@ void read_expr(block_t *parent, basic_block_t **bb)
2197
2235
if (get_operator_prio (top_op ) >= get_operator_prio (op )) {
2198
2236
rs2 = opstack_pop ();
2199
2237
rs1 = opstack_pop ();
2238
+
2239
+ /* Handle pointer arithmetic for addition and subtraction */
2240
+ if ((top_op == OP_add || top_op == OP_sub ) &&
2241
+ (rs1 -> ptr_level ||
2242
+ (rs1 -> type && rs1 -> type -> ptr_level > 0 ) ||
2243
+ rs2 -> ptr_level ||
2244
+ (rs2 -> type && rs2 -> type -> ptr_level > 0 ))) {
2245
+ var_t * ptr_var = NULL ;
2246
+ var_t * int_var = NULL ;
2247
+ int element_size = 0 ;
2248
+
2249
+ /* Determine which operand is the pointer */
2250
+ if (rs1 -> ptr_level ||
2251
+ (rs1 -> type && rs1 -> type -> ptr_level > 0 )) {
2252
+ ptr_var = rs1 ;
2253
+ int_var = rs2 ;
2254
+
2255
+ /* Calculate element size */
2256
+ if (rs1 -> ptr_level && rs1 -> type ) {
2257
+ element_size = rs1 -> type -> size ;
2258
+ } else if (rs1 -> type && rs1 -> type -> ptr_level > 0 ) {
2259
+ /* Typedef pointer */
2260
+ switch (rs1 -> type -> base_type ) {
2261
+ case TYPE_char :
2262
+ element_size = TY_char -> size ;
2263
+ break ;
2264
+ case TYPE_int :
2265
+ element_size = TY_int -> size ;
2266
+ break ;
2267
+ case TYPE_void :
2268
+ element_size = 1 ;
2269
+ break ;
2270
+ default :
2271
+ element_size =
2272
+ rs1 -> type ? rs1 -> type -> size : PTR_SIZE ;
2273
+ break ;
2274
+ }
2275
+ }
2276
+ } else if (rs2 -> ptr_level ||
2277
+ (rs2 -> type && rs2 -> type -> ptr_level > 0 )) {
2278
+ /* Only for addition (p + n == n + p) */
2279
+ if (top_op == OP_add ) {
2280
+ ptr_var = rs2 ;
2281
+ int_var = rs1 ;
2282
+
2283
+ /* Calculate element size */
2284
+ if (rs2 -> ptr_level && rs2 -> type ) {
2285
+ element_size = rs2 -> type -> size ;
2286
+ } else if (rs2 -> type &&
2287
+ rs2 -> type -> ptr_level > 0 ) {
2288
+ /* Typedef pointer */
2289
+ switch (rs2 -> type -> base_type ) {
2290
+ case TYPE_char :
2291
+ element_size = TY_char -> size ;
2292
+ break ;
2293
+ case TYPE_int :
2294
+ element_size = TY_int -> size ;
2295
+ break ;
2296
+ case TYPE_void :
2297
+ element_size = 1 ;
2298
+ break ;
2299
+ default :
2300
+ element_size = rs2 -> type
2301
+ ? rs2 -> type -> size
2302
+ : PTR_SIZE ;
2303
+ break ;
2304
+ }
2305
+ }
2306
+ /* Swap operands so pointer is rs1 */
2307
+ rs1 = ptr_var ;
2308
+ rs2 = int_var ;
2309
+ }
2310
+ }
2311
+
2312
+ /* If we need to scale the integer operand */
2313
+ if (ptr_var && element_size > 1 ) {
2314
+ /* Create multiplication by element size */
2315
+ var_t * size_const = require_var (parent );
2316
+ gen_name_to (size_const -> var_name );
2317
+ size_const -> init_val = element_size ;
2318
+ add_insn (parent , * bb , OP_load_constant , size_const ,
2319
+ NULL , NULL , 0 , NULL );
2320
+
2321
+ var_t * scaled = require_var (parent );
2322
+ gen_name_to (scaled -> var_name );
2323
+ add_insn (parent , * bb , OP_mul , scaled , int_var ,
2324
+ size_const , 0 , NULL );
2325
+
2326
+ /* Use scaled value as rs2 */
2327
+ rs2 = scaled ;
2328
+ }
2329
+ }
2330
+
2200
2331
vd = require_var (parent );
2201
2332
gen_name_to (vd -> var_name );
2202
2333
opstack_push (vd );
@@ -2312,6 +2443,92 @@ void read_expr(block_t *parent, basic_block_t **bb)
2312
2443
rs2 = opstack_pop ();
2313
2444
rs1 = opstack_pop ();
2314
2445
2446
+ /* Handle pointer arithmetic for addition and subtraction */
2447
+ if ((top_op == OP_add || top_op == OP_sub ) &&
2448
+ (rs1 -> ptr_level || (rs1 -> type && rs1 -> type -> ptr_level > 0 ) ||
2449
+ rs2 -> ptr_level || (rs2 -> type && rs2 -> type -> ptr_level > 0 ))) {
2450
+ var_t * ptr_var = NULL ;
2451
+ var_t * int_var = NULL ;
2452
+ int element_size = 0 ;
2453
+
2454
+ /* Determine which operand is the pointer */
2455
+ if (rs1 -> ptr_level || (rs1 -> type && rs1 -> type -> ptr_level > 0 )) {
2456
+ ptr_var = rs1 ;
2457
+ int_var = rs2 ;
2458
+
2459
+ /* Calculate element size */
2460
+ if (rs1 -> ptr_level && rs1 -> type ) {
2461
+ element_size = rs1 -> type -> size ;
2462
+ } else if (rs1 -> type && rs1 -> type -> ptr_level > 0 ) {
2463
+ /* Typedef pointer */
2464
+ switch (rs1 -> type -> base_type ) {
2465
+ case TYPE_char :
2466
+ element_size = TY_char -> size ;
2467
+ break ;
2468
+ case TYPE_int :
2469
+ element_size = TY_int -> size ;
2470
+ break ;
2471
+ case TYPE_void :
2472
+ element_size = 1 ;
2473
+ break ;
2474
+ default :
2475
+ element_size = rs1 -> type ? rs1 -> type -> size : PTR_SIZE ;
2476
+ break ;
2477
+ }
2478
+ }
2479
+ } else if (rs2 -> ptr_level ||
2480
+ (rs2 -> type && rs2 -> type -> ptr_level > 0 )) {
2481
+ /* Only for addition (p + n == n + p) */
2482
+ if (top_op == OP_add ) {
2483
+ ptr_var = rs2 ;
2484
+ int_var = rs1 ;
2485
+
2486
+ /* Calculate element size */
2487
+ if (rs2 -> ptr_level && rs2 -> type ) {
2488
+ element_size = rs2 -> type -> size ;
2489
+ } else if (rs2 -> type && rs2 -> type -> ptr_level > 0 ) {
2490
+ /* Typedef pointer */
2491
+ switch (rs2 -> type -> base_type ) {
2492
+ case TYPE_char :
2493
+ element_size = TY_char -> size ;
2494
+ break ;
2495
+ case TYPE_int :
2496
+ element_size = TY_int -> size ;
2497
+ break ;
2498
+ case TYPE_void :
2499
+ element_size = 1 ;
2500
+ break ;
2501
+ default :
2502
+ element_size =
2503
+ rs2 -> type ? rs2 -> type -> size : PTR_SIZE ;
2504
+ break ;
2505
+ }
2506
+ }
2507
+ /* Swap operands so pointer is rs1 */
2508
+ rs1 = ptr_var ;
2509
+ rs2 = int_var ;
2510
+ }
2511
+ }
2512
+
2513
+ /* If we need to scale the integer operand */
2514
+ if (ptr_var && element_size > 1 ) {
2515
+ /* Create multiplication by element size */
2516
+ var_t * size_const = require_var (parent );
2517
+ gen_name_to (size_const -> var_name );
2518
+ size_const -> init_val = element_size ;
2519
+ add_insn (parent , * bb , OP_load_constant , size_const , NULL , NULL ,
2520
+ 0 , NULL );
2521
+
2522
+ var_t * scaled = require_var (parent );
2523
+ gen_name_to (scaled -> var_name );
2524
+ add_insn (parent , * bb , OP_mul , scaled , int_var , size_const , 0 ,
2525
+ NULL );
2526
+
2527
+ /* Use scaled value as rs2 */
2528
+ rs2 = scaled ;
2529
+ }
2530
+ }
2531
+
2315
2532
/* Constant folding for binary operations */
2316
2533
if (rs1 && rs2 && rs1 -> init_val && !rs1 -> ptr_level && !rs1 -> is_global &&
2317
2534
rs2 -> init_val && !rs2 -> ptr_level && !rs2 -> is_global ) {
@@ -2462,11 +2679,16 @@ void read_lvalue(lvalue_t *lvalue,
2462
2679
}
2463
2680
2464
2681
/* var must be either a pointer or an array of some type */
2465
- if (var -> ptr_level == 0 && var -> array_size == 0 )
2682
+ /* For typedef pointers, check the type's ptr_level */
2683
+ bool is_typedef_pointer = (var -> type && var -> type -> ptr_level > 0 );
2684
+ if (var -> ptr_level == 0 && var -> array_size == 0 &&
2685
+ !is_typedef_pointer )
2466
2686
error ("Cannot apply square operator to non-pointer" );
2467
2687
2468
2688
/* if nested pointer, still pointer */
2469
- if (var -> ptr_level <= 1 && var -> array_size == 0 ) {
2689
+ /* Also handle typedef pointers which have ptr_level == 0 */
2690
+ if ((var -> ptr_level <= 1 || is_typedef_pointer ) &&
2691
+ var -> array_size == 0 ) {
2470
2692
/* For typedef pointers, get the size of the base type that the
2471
2693
* pointer points to
2472
2694
*/
@@ -2695,7 +2917,31 @@ void read_lvalue(lvalue_t *lvalue,
2695
2917
side_effect [se_idx ].opcode = OP_load_constant ;
2696
2918
vd = require_var (parent );
2697
2919
gen_name_to (vd -> var_name );
2698
- vd -> init_val = 1 ;
2920
+
2921
+ /* Calculate increment size based on pointer type */
2922
+ int increment_size = 1 ;
2923
+ if (lvalue -> ptr_level && !lvalue -> is_reference ) {
2924
+ increment_size = lvalue -> type -> size ;
2925
+ } else if (!lvalue -> is_reference && lvalue -> type &&
2926
+ lvalue -> type -> ptr_level > 0 ) {
2927
+ /* This is a typedef pointer */
2928
+ switch (lvalue -> type -> base_type ) {
2929
+ case TYPE_char :
2930
+ increment_size = TY_char -> size ;
2931
+ break ;
2932
+ case TYPE_int :
2933
+ increment_size = TY_int -> size ;
2934
+ break ;
2935
+ case TYPE_void :
2936
+ increment_size = 1 ;
2937
+ break ;
2938
+ default :
2939
+ increment_size = lvalue -> type -> size ;
2940
+ break ;
2941
+ }
2942
+ }
2943
+ vd -> init_val = increment_size ;
2944
+
2699
2945
side_effect [se_idx ].rd = vd ;
2700
2946
side_effect [se_idx ].rs1 = NULL ;
2701
2947
side_effect [se_idx ].rs2 = NULL ;
@@ -3010,6 +3256,27 @@ bool read_body_assignment(char *token,
3010
3256
*/
3011
3257
if (lvalue .ptr_level && !lvalue .is_reference )
3012
3258
increment_size = lvalue .type -> size ;
3259
+ /* Also check for typedef pointers which have is_ptr == 0 */
3260
+ else if (!lvalue .is_reference && lvalue .type &&
3261
+ lvalue .type -> ptr_level > 0 ) {
3262
+ /* This is a typedef pointer, get the base type size */
3263
+ switch (lvalue .type -> base_type ) {
3264
+ case TYPE_char :
3265
+ increment_size = TY_char -> size ;
3266
+ break ;
3267
+ case TYPE_int :
3268
+ increment_size = TY_int -> size ;
3269
+ break ;
3270
+ case TYPE_void :
3271
+ /* void pointers treated as byte pointers */
3272
+ increment_size = 1 ;
3273
+ break ;
3274
+ default :
3275
+ /* For struct pointers and other types */
3276
+ increment_size = lvalue .type -> size ;
3277
+ break ;
3278
+ }
3279
+ }
3013
3280
3014
3281
/* If operand is a reference, read the value and push to stack for
3015
3282
* the incoming addition/subtraction. Otherwise, use the top element
0 commit comments