Hi, I am starting a new thread on this issue. When processing following simple example: char *incr(char *p) { char *tmp = p; tmp += 5; return tmp; } The linearizer is taking the type of the expression 'tmp += 5' from the src operand which is unsigned long, instead of taking the type from the target operand which is char pointer. This results in following sequence: incr: .L000001CB177AD5C8: <entry-point> ptrcast.64 %r3 <- (64) %arg1 add.64 %r4 <- %r3, $5 cast.64 %r5 <- (64) %r4 ret.64 %r5 However if we make the change shown below then this output is produced which is correct I believe as in add or sub operations, if either left or right operand is a pointer and the other operand is an int then the result should be a pointer. incr: .L000001633F0BEE58: <entry-point> ptrcast.64 %r3 <- (64) %arg1 add.64 %r4 <- %r3, $5 ptrcast.64 %r5 <- (64) %r4 ret.64 %r5 The change required is in linearize_assignment() function. The suggested version is shown below. static pseudo_t linearize_assignment(struct entrypoint *ep, struct expression *expr) { ... int opcode; struct symbol *ctype = src->ctype; if (!src) return VOID_PSEUDO; oldvalue = cast_pseudo(ep, oldvalue, src->ctype, expr->ctype); opcode = opcode_sign(op_trans[expr->op - SPECIAL_BASE], src->ctype); if (opcode == OP_ADD || opcode == OP_SUB) { if (is_ptr_type(target->ctype)) { ctype = target->ctype; } dst = add_binary_op(ep, ctype, opcode, oldvalue, value); value = cast_pseudo(ep, dst, expr->ctype, ctype); ... } -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html