Re: Sparse-LLVM issue compiling NULL pointers

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

 



On Tue, Feb 28, 2017 at 06:03:05PM +0100, Luc Van Oostenryck wrote:
> On Tue, Feb 28, 2017 at 4:09 PM, Luc Van Oostenryck
> <luc.vanoostenryck@xxxxxxxxx> wrote:
> > There is indeed some problems regarding this, we looked a bit at this
> > some weeks ago. However I firmly believe that the information about
> > the type belong to the operations and not the values.
> 
> I've taken a very quick look at this "mt->foo = (void *)0"
> The type info is perfectly present.
> If in sparse-llvm.c:output_op_store() you add somewhere something like:
>     fprintf(stderr, "-> %s\n", show_typename(insn->type));
> You will see that it display the expected type: "int *".
> This is all the type info needed: it's the type of insn->target (the
> value to be stored)
> and the type of the dereferencing of insn->src (the (base) address).
> 
> The problem is that output_op_store() doesn't use this info, it tries to deduce
> this type via pseudo_to_value() but pseudo_to_value() wrongly assumes that all
> PSEUDO_VALUE-pseudo are integer.


Not very pretty and incomplete but the following patch allow sparse-llvm
to compile this:
	struct mytype {
		int *foo;
	};
	
	extern void init_mytype(struct mytype *mt);
	void init_mytype(struct mytype *mt)
	{
		mt->foo = (int *)mt;
		mt->foo = (void *)mt;
		mt->foo = (int *)0;
		mt->foo = (void *)0;
		mt->foo = (void *)(long)0;
	}

It fail at " ... = (... *)1;" though.


diff --git a/sparse-llvm.c b/sparse-llvm.c
index 9f362b3ed..9e0450ae7 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -306,6 +306,7 @@ static void pseudo_name(pseudo_t pseudo, char *buf)
 static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *insn, pseudo_t pseudo)
 {
 	LLVMValueRef result = NULL;
+	LLVMTypeRef type;
 
 	switch (pseudo->type) {
 	case PSEUDO_REG:
@@ -360,7 +361,21 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
 		break;
 	}
 	case PSEUDO_VAL:
-		result = LLVMConstInt(insn_symbol_type(fn->module, insn), pseudo->value, 1);
+		type = insn_symbol_type(fn->module, insn);
+		switch (LLVMGetTypeKind(type)) {
+		case LLVMPointerTypeKind:
+			assert(!pseudo->value);
+			result = LLVMConstPointerNull(type);
+			break;
+		case LLVMIntegerTypeKind:
+			result = LLVMConstInt(type, pseudo->value, 1);
+			break;
+		default:
+			assert(0);
+		}
 		break;
 	case PSEUDO_ARG: {
 		result = LLVMGetParam(fn->fn, pseudo->nr - 1);
@@ -626,6 +641,7 @@ static void output_op_store(struct function *fn, struct instruction *insn)
 
 	addr = calc_memop_addr(fn, insn);
 
 	target_in = pseudo_to_value(fn, insn, insn->target);
 
 	/* perform store */
--
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