aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--sparse-llvm.c31
-rw-r--r--validation/backend/constant-pointer.c24
-rw-r--r--validation/backend/type-constant.c23
3 files changed, 77 insertions, 1 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 3e519226..7c8e1bff 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -348,6 +348,35 @@ static LLVMValueRef get_sym_value(struct function *fn, struct symbol *sym)
return result;
}
+static LLVMValueRef constant_value(unsigned long long val, LLVMTypeRef dtype)
+{
+ LLVMTypeRef itype;
+ LLVMValueRef result;
+
+ switch (LLVMGetTypeKind(dtype)) {
+ case LLVMPointerTypeKind:
+ itype = LLVMIntType(bits_in_pointer);
+ result = LLVMConstInt(itype, val, 1);
+ result = LLVMConstIntToPtr(result, dtype);
+ break;
+ case LLVMIntegerTypeKind:
+ result = LLVMConstInt(dtype, val, 1);
+ break;
+ default:
+ assert(0);
+ }
+ return result;
+}
+
+static LLVMValueRef val_to_value(unsigned long long val, struct symbol *ctype)
+{
+ LLVMTypeRef dtype;
+
+ assert(ctype);
+ dtype = symbol_type(ctype);
+ return constant_value(val, dtype);
+}
+
static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *insn, pseudo_t pseudo)
{
LLVMValueRef result = NULL;
@@ -360,7 +389,7 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
result = get_sym_value(fn, pseudo->sym);
break;
case PSEUDO_VAL:
- result = LLVMConstInt(insn_symbol_type(insn), pseudo->value, 1);
+ result = val_to_value(pseudo->value, insn->type);
break;
case PSEUDO_ARG: {
result = LLVMGetParam(fn->fn, pseudo->nr - 1);
diff --git a/validation/backend/constant-pointer.c b/validation/backend/constant-pointer.c
new file mode 100644
index 00000000..9012c784
--- /dev/null
+++ b/validation/backend/constant-pointer.c
@@ -0,0 +1,24 @@
+extern int *ip[];
+
+void foo(void);
+void foo(void)
+{
+ ip[0] = (void *)0L;
+ ip[1] = (int *)0L;
+ ip[2] = (void *)0;
+ ip[3] = (int *)0;
+ ip[4] = (void *)(long)0;
+ ip[5] = (int *)(long)0;
+ ip[6] = (void *)123;
+ ip[7] = (int *)123;
+ ip[8] = (void *)123L;
+ ip[9] = (int *)123L;
+ ip[10] = (void *)(long)123;
+ ip[11] = (int *)(long)123;
+}
+
+/*
+ * check-name: constant pointers
+ * check-command: sparse-llvm $file
+ * check-output-ignore
+ */
diff --git a/validation/backend/type-constant.c b/validation/backend/type-constant.c
new file mode 100644
index 00000000..cded7f2e
--- /dev/null
+++ b/validation/backend/type-constant.c
@@ -0,0 +1,23 @@
+char creti(void) { return 3; }
+int ireti(void) { return 3; }
+long lreti(void) { return 3; }
+
+char cinii(void) { char r = 3; return r; }
+int iinii(void) { int r = 3; return r; }
+long linii(void) { long r = 3; return r; }
+
+
+void *vretn(void) { return (void*)0; }
+char *cretn(void) { return (void*)0; }
+int *iretn(void) { return (void*)0; }
+long *lretn(void) { return (void*)0; }
+
+void *vinin(void) { void *r = (void*)0; return r; }
+char *cinin(void) { char *r = (void*)0; return r; }
+int *iinin(void) { int *r = (void*)0; return r; }
+long *linin(void) { long *r = (void*)0; return r; }
+
+/*
+ * check-name: type-constant
+ * check-command: ./sparsec -Wno-decl -c $file -o r.o
+ */