@@ -4398,6 +4398,25 @@ void c_typecheck_baset::typecheck_arithmetic_pointer(exprt &expr)
43984398 }
43994399}
44004400
4401+ // / GCC's arithmetic on `void *' (an extension, "Pointer Arith" in the GCC
4402+ // / manual) computes with a size of 1, and the result has the pointer's type:
4403+ // / `p + 8' for a `void *' p is a `void *'. typecheck_arithmetic_pointer
4404+ // / computes it on `char *'; cast the result \p expr of the pointer
4405+ // / arithmetic back to \p pointer_type, the type of the pointer operand. A
4406+ // / compound assignment (`p += 8') is cast by the assignment itself.
4407+ static void keep_void_pointer_type (exprt &expr, const typet &pointer_type)
4408+ {
4409+ if (
4410+ expr.id () == ID_side_effect ||
4411+ to_pointer_type (pointer_type).base_type ().id () != ID_empty ||
4412+ expr.type () == pointer_type)
4413+ {
4414+ return ;
4415+ }
4416+ typecast_exprt result{expr, pointer_type};
4417+ expr.swap (result);
4418+ }
4419+
44014420void c_typecheck_baset::typecheck_expr_pointer_arithmetic (exprt &expr)
44024421{
44034422 auto &binary_expr = to_binary_expr (expr);
@@ -4432,9 +4451,11 @@ void c_typecheck_baset::typecheck_expr_pointer_arithmetic(exprt &expr)
44324451 type1.id ()==ID_c_bit_field ||
44334452 type1.id ()==ID_c_enum_tag))
44344453 {
4454+ const typet pointer_type = type0;
44354455 typecheck_arithmetic_pointer (op0);
44364456 make_index_type (op1);
44374457 expr.type () = op0.type ();
4458+ keep_void_pointer_type (expr, pointer_type);
44384459 return ;
44394460 }
44404461 }
@@ -4468,9 +4489,11 @@ void c_typecheck_baset::typecheck_expr_pointer_arithmetic(exprt &expr)
44684489 int_op_type.id ()==ID_c_bit_field ||
44694490 int_op_type.id ()==ID_c_enum_tag)
44704491 {
4492+ const typet pointer_type = p_op->type ();
44714493 typecheck_arithmetic_pointer (*p_op);
44724494 make_index_type (*int_op);
44734495 expr.type ()=p_op->type ();
4496+ keep_void_pointer_type (expr, pointer_type);
44744497 return ;
44754498 }
44764499 }
0 commit comments