@@ -1250,10 +1250,6 @@ void read_full_var_decl(var_t *vd, int anon, int is_param)
12501250
12511251 vd -> type = type ;
12521252
1253- /* Inherit pointer level from typedef */
1254- if (type -> ptr_level > 0 )
1255- vd -> is_ptr = type -> ptr_level ;
1256-
12571253 read_inner_var_decl (vd , anon , is_param );
12581254}
12591255
@@ -1528,8 +1524,28 @@ void handle_single_dereference(block_t *parent, basic_block_t **bb)
15281524 vd = require_deref_var (parent , var -> type , var -> is_ptr );
15291525 if (lvalue .is_ptr > 1 )
15301526 sz = PTR_SIZE ;
1531- else
1532- sz = lvalue .type -> size ;
1527+ else {
1528+ /* For typedef pointers, get the size of the pointed-to type */
1529+ if (lvalue .type && lvalue .type -> ptr_level > 0 ) {
1530+ /* This is a typedef pointer */
1531+ switch (lvalue .type -> base_type ) {
1532+ case TYPE_char :
1533+ sz = TY_char -> size ;
1534+ break ;
1535+ case TYPE_int :
1536+ sz = TY_int -> size ;
1537+ break ;
1538+ case TYPE_void :
1539+ sz = 1 ;
1540+ break ;
1541+ default :
1542+ sz = lvalue .type -> size ;
1543+ break ;
1544+ }
1545+ } else {
1546+ sz = lvalue .type -> size ;
1547+ }
1548+ }
15331549 gen_name_to (vd -> var_name );
15341550 opstack_push (vd );
15351551 add_insn (parent , * bb , OP_read , vd , rs1 , NULL , sz , NULL );
@@ -1587,8 +1603,29 @@ void handle_multiple_dereference(block_t *parent, basic_block_t **bb)
15871603 lvalue .is_ptr > i ? lvalue .is_ptr - i - 1 : 0 );
15881604 if (lvalue .is_ptr > i + 1 )
15891605 sz = PTR_SIZE ;
1590- else
1591- sz = lvalue .type -> size ;
1606+ else {
1607+ /* For typedef pointers, get the size of the pointed-to type */
1608+ if (lvalue .type && lvalue .type -> ptr_level > 0 &&
1609+ i == deref_count - 1 ) {
1610+ /* This is a typedef pointer on the final dereference */
1611+ switch (lvalue .type -> base_type ) {
1612+ case TYPE_char :
1613+ sz = TY_char -> size ;
1614+ break ;
1615+ case TYPE_int :
1616+ sz = TY_int -> size ;
1617+ break ;
1618+ case TYPE_void :
1619+ sz = 1 ;
1620+ break ;
1621+ default :
1622+ sz = lvalue .type -> size ;
1623+ break ;
1624+ }
1625+ } else {
1626+ sz = lvalue .type -> size ;
1627+ }
1628+ }
15921629 gen_name_to (vd -> var_name );
15931630 opstack_push (vd );
15941631 add_insn (parent , * bb , OP_read , vd , rs1 , NULL , sz , NULL );
@@ -2156,6 +2193,99 @@ void read_expr(block_t *parent, basic_block_t **bb)
21562193 if (get_operator_prio (top_op ) >= get_operator_prio (op )) {
21572194 rs2 = opstack_pop ();
21582195 rs1 = opstack_pop ();
2196+
2197+ /* Handle pointer arithmetic for addition and subtraction */
2198+ if ((top_op == OP_add || top_op == OP_sub ) &&
2199+ (rs1 -> is_ptr ||
2200+ (rs1 -> type && rs1 -> type -> ptr_level > 0 ) ||
2201+ rs2 -> is_ptr ||
2202+ (rs2 -> type && rs2 -> type -> ptr_level > 0 ))) {
2203+ var_t * ptr_var = NULL ;
2204+ var_t * int_var = NULL ;
2205+ int element_size = 0 ;
2206+
2207+ /* Determine which operand is the pointer */
2208+ if (rs1 -> is_ptr ||
2209+ (rs1 -> type && rs1 -> type -> ptr_level > 0 )) {
2210+ ptr_var = rs1 ;
2211+ int_var = rs2 ;
2212+
2213+ /* Calculate element size */
2214+ if (rs1 -> is_ptr && rs1 -> type ) {
2215+ element_size = rs1 -> type -> size ;
2216+ } else if (rs1 -> type && rs1 -> type -> ptr_level > 0 ) {
2217+ /* Typedef pointer */
2218+ switch (rs1 -> type -> base_type ) {
2219+ case TYPE_char :
2220+ element_size = TY_char -> size ;
2221+ break ;
2222+ case TYPE_int :
2223+ element_size = TY_int -> size ;
2224+ break ;
2225+ case TYPE_void :
2226+ element_size = 1 ;
2227+ break ;
2228+ default :
2229+ element_size =
2230+ rs1 -> type ? rs1 -> type -> size : PTR_SIZE ;
2231+ break ;
2232+ }
2233+ }
2234+ } else if (rs2 -> is_ptr ||
2235+ (rs2 -> type && rs2 -> type -> ptr_level > 0 )) {
2236+ /* Only for addition (p + n == n + p) */
2237+ if (top_op == OP_add ) {
2238+ ptr_var = rs2 ;
2239+ int_var = rs1 ;
2240+
2241+ /* Calculate element size */
2242+ if (rs2 -> is_ptr && rs2 -> type ) {
2243+ element_size = rs2 -> type -> size ;
2244+ } else if (rs2 -> type &&
2245+ rs2 -> type -> ptr_level > 0 ) {
2246+ /* Typedef pointer */
2247+ switch (rs2 -> type -> base_type ) {
2248+ case TYPE_char :
2249+ element_size = TY_char -> size ;
2250+ break ;
2251+ case TYPE_int :
2252+ element_size = TY_int -> size ;
2253+ break ;
2254+ case TYPE_void :
2255+ element_size = 1 ;
2256+ break ;
2257+ default :
2258+ element_size = rs2 -> type
2259+ ? rs2 -> type -> size
2260+ : PTR_SIZE ;
2261+ break ;
2262+ }
2263+ }
2264+ /* Swap operands so pointer is rs1 */
2265+ rs1 = ptr_var ;
2266+ rs2 = int_var ;
2267+ }
2268+ }
2269+
2270+ /* If we need to scale the integer operand */
2271+ if (ptr_var && element_size > 1 ) {
2272+ /* Create multiplication by element size */
2273+ var_t * size_const = require_var (parent );
2274+ gen_name_to (size_const -> var_name );
2275+ size_const -> init_val = element_size ;
2276+ add_insn (parent , * bb , OP_load_constant , size_const ,
2277+ NULL , NULL , 0 , NULL );
2278+
2279+ var_t * scaled = require_var (parent );
2280+ gen_name_to (scaled -> var_name );
2281+ add_insn (parent , * bb , OP_mul , scaled , int_var ,
2282+ size_const , 0 , NULL );
2283+
2284+ /* Use scaled value as rs2 */
2285+ rs2 = scaled ;
2286+ }
2287+ }
2288+
21592289 vd = require_var (parent );
21602290 gen_name_to (vd -> var_name );
21612291 opstack_push (vd );
@@ -2271,6 +2401,91 @@ void read_expr(block_t *parent, basic_block_t **bb)
22712401 rs2 = opstack_pop ();
22722402 rs1 = opstack_pop ();
22732403
2404+ /* Handle pointer arithmetic for addition and subtraction */
2405+ if ((top_op == OP_add || top_op == OP_sub ) &&
2406+ (rs1 -> is_ptr || (rs1 -> type && rs1 -> type -> ptr_level > 0 ) ||
2407+ rs2 -> is_ptr || (rs2 -> type && rs2 -> type -> ptr_level > 0 ))) {
2408+ var_t * ptr_var = NULL ;
2409+ var_t * int_var = NULL ;
2410+ int element_size = 0 ;
2411+
2412+ /* Determine which operand is the pointer */
2413+ if (rs1 -> is_ptr || (rs1 -> type && rs1 -> type -> ptr_level > 0 )) {
2414+ ptr_var = rs1 ;
2415+ int_var = rs2 ;
2416+
2417+ /* Calculate element size */
2418+ if (rs1 -> is_ptr && rs1 -> type ) {
2419+ element_size = rs1 -> type -> size ;
2420+ } else if (rs1 -> type && rs1 -> type -> ptr_level > 0 ) {
2421+ /* Typedef pointer */
2422+ switch (rs1 -> type -> base_type ) {
2423+ case TYPE_char :
2424+ element_size = TY_char -> size ;
2425+ break ;
2426+ case TYPE_int :
2427+ element_size = TY_int -> size ;
2428+ break ;
2429+ case TYPE_void :
2430+ element_size = 1 ;
2431+ break ;
2432+ default :
2433+ element_size = rs1 -> type ? rs1 -> type -> size : PTR_SIZE ;
2434+ break ;
2435+ }
2436+ }
2437+ } else if (rs2 -> is_ptr || (rs2 -> type && rs2 -> type -> ptr_level > 0 )) {
2438+ /* Only for addition (p + n == n + p) */
2439+ if (top_op == OP_add ) {
2440+ ptr_var = rs2 ;
2441+ int_var = rs1 ;
2442+
2443+ /* Calculate element size */
2444+ if (rs2 -> is_ptr && rs2 -> type ) {
2445+ element_size = rs2 -> type -> size ;
2446+ } else if (rs2 -> type && rs2 -> type -> ptr_level > 0 ) {
2447+ /* Typedef pointer */
2448+ switch (rs2 -> type -> base_type ) {
2449+ case TYPE_char :
2450+ element_size = TY_char -> size ;
2451+ break ;
2452+ case TYPE_int :
2453+ element_size = TY_int -> size ;
2454+ break ;
2455+ case TYPE_void :
2456+ element_size = 1 ;
2457+ break ;
2458+ default :
2459+ element_size =
2460+ rs2 -> type ? rs2 -> type -> size : PTR_SIZE ;
2461+ break ;
2462+ }
2463+ }
2464+ /* Swap operands so pointer is rs1 */
2465+ rs1 = ptr_var ;
2466+ rs2 = int_var ;
2467+ }
2468+ }
2469+
2470+ /* If we need to scale the integer operand */
2471+ if (ptr_var && element_size > 1 ) {
2472+ /* Create multiplication by element size */
2473+ var_t * size_const = require_var (parent );
2474+ gen_name_to (size_const -> var_name );
2475+ size_const -> init_val = element_size ;
2476+ add_insn (parent , * bb , OP_load_constant , size_const , NULL , NULL ,
2477+ 0 , NULL );
2478+
2479+ var_t * scaled = require_var (parent );
2480+ gen_name_to (scaled -> var_name );
2481+ add_insn (parent , * bb , OP_mul , scaled , int_var , size_const , 0 ,
2482+ NULL );
2483+
2484+ /* Use scaled value as rs2 */
2485+ rs2 = scaled ;
2486+ }
2487+ }
2488+
22742489 /* Constant folding for binary operations */
22752490 if (rs1 && rs2 && rs1 -> init_val && !rs1 -> is_ptr && !rs1 -> is_global &&
22762491 rs2 -> init_val && !rs2 -> is_ptr && !rs2 -> is_global ) {
@@ -2421,11 +2636,15 @@ void read_lvalue(lvalue_t *lvalue,
24212636 }
24222637
24232638 /* var must be either a pointer or an array of some type */
2424- if (var -> is_ptr == 0 && var -> array_size == 0 )
2639+ /* For typedef pointers, check the type's ptr_level */
2640+ bool is_typedef_pointer = (var -> type && var -> type -> ptr_level > 0 );
2641+ if (var -> is_ptr == 0 && var -> array_size == 0 && !is_typedef_pointer )
24252642 error ("Cannot apply square operator to non-pointer" );
24262643
24272644 /* if nested pointer, still pointer */
2428- if (var -> is_ptr <= 1 && var -> array_size == 0 ) {
2645+ /* Also handle typedef pointers which have is_ptr == 0 */
2646+ if ((var -> is_ptr <= 1 || is_typedef_pointer ) &&
2647+ var -> array_size == 0 ) {
24292648 /* For typedef pointers, get the size of the base type that the
24302649 * pointer points to
24312650 */
@@ -2645,7 +2864,31 @@ void read_lvalue(lvalue_t *lvalue,
26452864 side_effect [se_idx ].opcode = OP_load_constant ;
26462865 vd = require_var (parent );
26472866 gen_name_to (vd -> var_name );
2648- vd -> init_val = 1 ;
2867+
2868+ /* Calculate increment size based on pointer type */
2869+ int increment_size = 1 ;
2870+ if (lvalue -> is_ptr && !lvalue -> is_reference ) {
2871+ increment_size = lvalue -> type -> size ;
2872+ } else if (!lvalue -> is_reference && lvalue -> type &&
2873+ lvalue -> type -> ptr_level > 0 ) {
2874+ /* This is a typedef pointer */
2875+ switch (lvalue -> type -> base_type ) {
2876+ case TYPE_char :
2877+ increment_size = TY_char -> size ;
2878+ break ;
2879+ case TYPE_int :
2880+ increment_size = TY_int -> size ;
2881+ break ;
2882+ case TYPE_void :
2883+ increment_size = 1 ;
2884+ break ;
2885+ default :
2886+ increment_size = lvalue -> type -> size ;
2887+ break ;
2888+ }
2889+ }
2890+ vd -> init_val = increment_size ;
2891+
26492892 side_effect [se_idx ].rd = vd ;
26502893 side_effect [se_idx ].rs1 = NULL ;
26512894 side_effect [se_idx ].rs2 = NULL ;
@@ -2960,6 +3203,27 @@ bool read_body_assignment(char *token,
29603203 */
29613204 if (lvalue .is_ptr && !lvalue .is_reference )
29623205 increment_size = lvalue .type -> size ;
3206+ /* Also check for typedef pointers which have is_ptr == 0 */
3207+ else if (!lvalue .is_reference && lvalue .type &&
3208+ lvalue .type -> ptr_level > 0 ) {
3209+ /* This is a typedef pointer, get the base type size */
3210+ switch (lvalue .type -> base_type ) {
3211+ case TYPE_char :
3212+ increment_size = TY_char -> size ;
3213+ break ;
3214+ case TYPE_int :
3215+ increment_size = TY_int -> size ;
3216+ break ;
3217+ case TYPE_void :
3218+ /* void pointers treated as byte pointers */
3219+ increment_size = 1 ;
3220+ break ;
3221+ default :
3222+ /* For struct pointers and other types */
3223+ increment_size = lvalue .type -> size ;
3224+ break ;
3225+ }
3226+ }
29633227
29643228 /* If operand is a reference, read the value and push to stack for
29653229 * the incoming addition/subtraction. Otherwise, use the top element
0 commit comments