@@ -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
@@ -2156,6 +2152,96 @@ void read_expr(block_t *parent, basic_block_t **bb)
21562152 if (get_operator_prio (top_op ) >= get_operator_prio (op )) {
21572153 rs2 = opstack_pop ();
21582154 rs1 = opstack_pop ();
2155+
2156+ /* Handle pointer arithmetic for addition and subtraction */
2157+ if ((top_op == OP_add || top_op == OP_sub ) &&
2158+ (rs1 -> is_ptr ||
2159+ (rs1 -> type && rs1 -> type -> ptr_level > 0 ) ||
2160+ rs2 -> is_ptr ||
2161+ (rs2 -> type && rs2 -> type -> ptr_level > 0 ))) {
2162+ var_t * ptr_var = NULL ;
2163+ var_t * int_var = NULL ;
2164+ int element_size = 0 ;
2165+
2166+ /* Determine which operand is the pointer */
2167+ if (rs1 -> is_ptr ||
2168+ (rs1 -> type && rs1 -> type -> ptr_level > 0 )) {
2169+ ptr_var = rs1 ;
2170+ int_var = rs2 ;
2171+
2172+ /* Calculate element size */
2173+ if (rs1 -> is_ptr ) {
2174+ element_size = rs1 -> type -> size ;
2175+ } else if (rs1 -> type && rs1 -> type -> ptr_level > 0 ) {
2176+ /* Typedef pointer */
2177+ switch (rs1 -> type -> base_type ) {
2178+ case TYPE_char :
2179+ element_size = TY_char -> size ;
2180+ break ;
2181+ case TYPE_int :
2182+ element_size = TY_int -> size ;
2183+ break ;
2184+ case TYPE_void :
2185+ element_size = 1 ;
2186+ break ;
2187+ default :
2188+ element_size = rs1 -> type -> size ;
2189+ break ;
2190+ }
2191+ }
2192+ } else if (rs2 -> is_ptr ||
2193+ (rs2 -> type && rs2 -> type -> ptr_level > 0 )) {
2194+ /* Only for addition (p + n == n + p) */
2195+ if (top_op == OP_add ) {
2196+ ptr_var = rs2 ;
2197+ int_var = rs1 ;
2198+
2199+ /* Calculate element size */
2200+ if (rs2 -> is_ptr ) {
2201+ element_size = rs2 -> type -> size ;
2202+ } else if (rs2 -> type &&
2203+ rs2 -> type -> ptr_level > 0 ) {
2204+ /* Typedef pointer */
2205+ switch (rs2 -> type -> base_type ) {
2206+ case TYPE_char :
2207+ element_size = TY_char -> size ;
2208+ break ;
2209+ case TYPE_int :
2210+ element_size = TY_int -> size ;
2211+ break ;
2212+ case TYPE_void :
2213+ element_size = 1 ;
2214+ break ;
2215+ default :
2216+ element_size = rs2 -> type -> size ;
2217+ break ;
2218+ }
2219+ }
2220+ /* Swap operands so pointer is rs1 */
2221+ rs1 = ptr_var ;
2222+ rs2 = int_var ;
2223+ }
2224+ }
2225+
2226+ /* If we need to scale the integer operand */
2227+ if (ptr_var && element_size > 1 ) {
2228+ /* Create multiplication by element size */
2229+ var_t * size_const = require_var (parent );
2230+ gen_name_to (size_const -> var_name );
2231+ size_const -> init_val = element_size ;
2232+ add_insn (parent , * bb , OP_load_constant , size_const ,
2233+ NULL , NULL , 0 , NULL );
2234+
2235+ var_t * scaled = require_var (parent );
2236+ gen_name_to (scaled -> var_name );
2237+ add_insn (parent , * bb , OP_mul , scaled , int_var ,
2238+ size_const , 0 , NULL );
2239+
2240+ /* Use scaled value as rs2 */
2241+ rs2 = scaled ;
2242+ }
2243+ }
2244+
21592245 vd = require_var (parent );
21602246 gen_name_to (vd -> var_name );
21612247 opstack_push (vd );
@@ -2271,6 +2357,90 @@ void read_expr(block_t *parent, basic_block_t **bb)
22712357 rs2 = opstack_pop ();
22722358 rs1 = opstack_pop ();
22732359
2360+ /* Handle pointer arithmetic for addition and subtraction */
2361+ if ((top_op == OP_add || top_op == OP_sub ) &&
2362+ (rs1 -> is_ptr || (rs1 -> type && rs1 -> type -> ptr_level > 0 ) ||
2363+ rs2 -> is_ptr || (rs2 -> type && rs2 -> type -> ptr_level > 0 ))) {
2364+ var_t * ptr_var = NULL ;
2365+ var_t * int_var = NULL ;
2366+ int element_size = 0 ;
2367+
2368+ /* Determine which operand is the pointer */
2369+ if (rs1 -> is_ptr || (rs1 -> type && rs1 -> type -> ptr_level > 0 )) {
2370+ ptr_var = rs1 ;
2371+ int_var = rs2 ;
2372+
2373+ /* Calculate element size */
2374+ if (rs1 -> is_ptr ) {
2375+ element_size = rs1 -> type -> size ;
2376+ } else if (rs1 -> type && rs1 -> type -> ptr_level > 0 ) {
2377+ /* Typedef pointer */
2378+ switch (rs1 -> type -> base_type ) {
2379+ case TYPE_char :
2380+ element_size = TY_char -> size ;
2381+ break ;
2382+ case TYPE_int :
2383+ element_size = TY_int -> size ;
2384+ break ;
2385+ case TYPE_void :
2386+ element_size = 1 ;
2387+ break ;
2388+ default :
2389+ element_size = rs1 -> type -> size ;
2390+ break ;
2391+ }
2392+ }
2393+ } else if (rs2 -> is_ptr || (rs2 -> type && rs2 -> type -> ptr_level > 0 )) {
2394+ /* Only for addition (p + n == n + p) */
2395+ if (top_op == OP_add ) {
2396+ ptr_var = rs2 ;
2397+ int_var = rs1 ;
2398+
2399+ /* Calculate element size */
2400+ if (rs2 -> is_ptr ) {
2401+ element_size = rs2 -> type -> size ;
2402+ } else if (rs2 -> type && rs2 -> type -> ptr_level > 0 ) {
2403+ /* Typedef pointer */
2404+ switch (rs2 -> type -> base_type ) {
2405+ case TYPE_char :
2406+ element_size = TY_char -> size ;
2407+ break ;
2408+ case TYPE_int :
2409+ element_size = TY_int -> size ;
2410+ break ;
2411+ case TYPE_void :
2412+ element_size = 1 ;
2413+ break ;
2414+ default :
2415+ element_size = rs2 -> type -> size ;
2416+ break ;
2417+ }
2418+ }
2419+ /* Swap operands so pointer is rs1 */
2420+ rs1 = ptr_var ;
2421+ rs2 = int_var ;
2422+ }
2423+ }
2424+
2425+ /* If we need to scale the integer operand */
2426+ if (ptr_var && element_size > 1 ) {
2427+ /* Create multiplication by element size */
2428+ var_t * size_const = require_var (parent );
2429+ gen_name_to (size_const -> var_name );
2430+ size_const -> init_val = element_size ;
2431+ add_insn (parent , * bb , OP_load_constant , size_const , NULL , NULL ,
2432+ 0 , NULL );
2433+
2434+ var_t * scaled = require_var (parent );
2435+ gen_name_to (scaled -> var_name );
2436+ add_insn (parent , * bb , OP_mul , scaled , int_var , size_const , 0 ,
2437+ NULL );
2438+
2439+ /* Use scaled value as rs2 */
2440+ rs2 = scaled ;
2441+ }
2442+ }
2443+
22742444 /* Constant folding for binary operations */
22752445 if (rs1 && rs2 && rs1 -> init_val && !rs1 -> is_ptr && !rs1 -> is_global &&
22762446 rs2 -> init_val && !rs2 -> is_ptr && !rs2 -> is_global ) {
@@ -2421,11 +2591,15 @@ void read_lvalue(lvalue_t *lvalue,
24212591 }
24222592
24232593 /* var must be either a pointer or an array of some type */
2424- if (var -> is_ptr == 0 && var -> array_size == 0 )
2594+ /* For typedef pointers, check the type's ptr_level */
2595+ bool is_typedef_pointer = (var -> type && var -> type -> ptr_level > 0 );
2596+ if (var -> is_ptr == 0 && var -> array_size == 0 && !is_typedef_pointer )
24252597 error ("Cannot apply square operator to non-pointer" );
24262598
24272599 /* if nested pointer, still pointer */
2428- if (var -> is_ptr <= 1 && var -> array_size == 0 ) {
2600+ /* Also handle typedef pointers which have is_ptr == 0 */
2601+ if ((var -> is_ptr <= 1 || is_typedef_pointer ) &&
2602+ var -> array_size == 0 ) {
24292603 /* For typedef pointers, get the size of the base type that the
24302604 * pointer points to
24312605 */
@@ -2645,7 +2819,31 @@ void read_lvalue(lvalue_t *lvalue,
26452819 side_effect [se_idx ].opcode = OP_load_constant ;
26462820 vd = require_var (parent );
26472821 gen_name_to (vd -> var_name );
2648- vd -> init_val = 1 ;
2822+
2823+ /* Calculate increment size based on pointer type */
2824+ int increment_size = 1 ;
2825+ if (lvalue -> is_ptr && !lvalue -> is_reference ) {
2826+ increment_size = lvalue -> type -> size ;
2827+ } else if (!lvalue -> is_reference && lvalue -> type &&
2828+ lvalue -> type -> ptr_level > 0 ) {
2829+ /* This is a typedef pointer */
2830+ switch (lvalue -> type -> base_type ) {
2831+ case TYPE_char :
2832+ increment_size = TY_char -> size ;
2833+ break ;
2834+ case TYPE_int :
2835+ increment_size = TY_int -> size ;
2836+ break ;
2837+ case TYPE_void :
2838+ increment_size = 1 ;
2839+ break ;
2840+ default :
2841+ increment_size = lvalue -> type -> size ;
2842+ break ;
2843+ }
2844+ }
2845+ vd -> init_val = increment_size ;
2846+
26492847 side_effect [se_idx ].rd = vd ;
26502848 side_effect [se_idx ].rs1 = NULL ;
26512849 side_effect [se_idx ].rs2 = NULL ;
@@ -2960,6 +3158,27 @@ bool read_body_assignment(char *token,
29603158 */
29613159 if (lvalue .is_ptr && !lvalue .is_reference )
29623160 increment_size = lvalue .type -> size ;
3161+ /* Also check for typedef pointers which have is_ptr == 0 */
3162+ else if (!lvalue .is_reference && lvalue .type &&
3163+ lvalue .type -> ptr_level > 0 ) {
3164+ /* This is a typedef pointer, get the base type size */
3165+ switch (lvalue .type -> base_type ) {
3166+ case TYPE_char :
3167+ increment_size = TY_char -> size ;
3168+ break ;
3169+ case TYPE_int :
3170+ increment_size = TY_int -> size ;
3171+ break ;
3172+ case TYPE_void :
3173+ /* void pointers treated as byte pointers */
3174+ increment_size = 1 ;
3175+ break ;
3176+ default :
3177+ /* For struct pointers and other types */
3178+ increment_size = lvalue .type -> size ;
3179+ break ;
3180+ }
3181+ }
29633182
29643183 /* If operand is a reference, read the value and push to stack for
29653184 * the incoming addition/subtraction. Otherwise, use the top element
0 commit comments