simplify: conservative handling of casts with pointers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux