When the cast is optimized out/target pointer type information lost, it may be impossible to for backend to recover it (think of "struct foo *my_new_foo = malloc(sizeof(*my_new_foo))"). Losing such pointer type information can be wider issue (structs and unions maybe), but this is the most exposed one and the patch tries to be minimal in this regard and the impact seems to be minimal too as usually type-correctness is followed. Annotated demonstration of the change (part of "test-linearize allocate.c", function allocate): before: .L0x7fd091ecb510: load.32 %r76 <- 20[%arg1] cast.64 %r78 <- (32) %r76 call.64 %r79 <- blob_alloc, %r78 >>> no cast, %r79 is generic void * br %r79, .L0x7fd091ecb650, .L0x7fd091ecb600 .L0x7fd091ecb600: call die, "out of memory" br .L0x7fd091ecb650 .L0x7fd091ecb650: load.32 %r85 <- 36[%arg1] add.32 %r87 <- %r85, %r76 store.32 %r87 -> 36[%arg1] >>> oops, cannot reconstruct what entity is being accessed from 0[%r79] store.64 %r30(blob) -> 0[%r79] >>> in this case, it is unambiguous, but we could be lost easily store.64 %r79 -> 8[%arg1] add.64 %r98 <- %r28, $15 [...] after: .L0x7fab5bc11510: load.32 %r76 <- 20[%arg1] cast.64 %r78 <- (32) %r76 call.64 %r79 <- blob_alloc, %r78 >>> this cast from void * is kept, target pointer type preserved cast.64 %r80 <- (64) %r79 br %r80, .L0x7fab5bc11650, .L0x7fab5bc11600 .L0x7fab5bc11600: call die, "out of memory" br .L0x7fab5bc11650 .L0x7fab5bc11650: load.32 %r85 <- 36[%arg1] add.32 %r87 <- %r85, %r76 store.32 %r87 -> 36[%arg1] >>> when we know the type of destination, we can reconstruct it >>> (newblob->next = blob) store.64 %r30(blob) -> 0[%r80] >>> and also, based on types + offset, we can infer correct >>> destination within %arg1 (desc->blobs = newblob) store.64 %r80 -> 8[%arg1] add.64 %r98 <- %r28, $15 [...] Signed-off-by: Jan Pokorný <pokorny_jan@xxxxxxxxx> --- simplify.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/simplify.c b/simplify.c index 8200584..3b2b03c 100644 --- a/simplify.c +++ b/simplify.c @@ -10,6 +10,7 @@ #include "expression.h" #include "linearize.h" #include "flow.h" +#include "symbol.h" /* Find the trivial parent for a phi-source */ static struct basic_block *phi_parent(struct basic_block *source, pseudo_t pseudo) @@ -667,6 +668,13 @@ static int simplify_cast(struct instruction *insn) orig_type = insn->orig_type; if (!orig_type) return 0; + + /* Avoid possible loss of pointer type info (OP_PTRCAST skipped below) */ + if (is_ptr_type(orig_type) != is_ptr_type(insn->type)) + return 0; /* non-pointer vs. pointer or viceversa */ + else if (orig_type->type == SYM_PTR && insn->opcode != OP_PTRCAST) + return 0; /* any type from "void *" (see alloc_cast_instruction) */ + orig_size = orig_type->bit_size; size = insn->size; src = insn->src; -- 1.7.3.4 -- 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