aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-11-16 21:24:27 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-11-17 10:04:37 +0100
commit5bd565dd77ec91c992e01638cc8f32d6bc51b44a (patch)
tree9879684be782dce0376ee8762f65ee2bd8bcda58
parentf48b9566eba161bdce4bf4c4af2839ce6843b90e (diff)
downloadsparse-dev-5bd565dd77ec91c992e01638cc8f32d6bc51b44a.tar.gz
llvm: fix variadic calls with constants
The linearized code, sparse's IR, have no use of C's complex type system. Those types are checked in previous phases and the pseudos doesn't have a type directly attached to them as all the needed typing info info are conveyed by the instructions. In particular, PSEUDO_VAL (used for integer and address constants) are completely typeless. There is a problem with this when calling a variadic function with a constant argument as in this case there is no type in the function prototype (for the variadic part, of course) and there is no defining instructions holding the type of the argument. Fiw this by using the type of the arguments explicitly given in the OP_CALL instructions. Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--sparse-llvm.c6
-rw-r--r--validation/backend/call-variadic.c1
2 files changed, 5 insertions, 2 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 1713367a..08f055a9 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -787,6 +787,7 @@ static void output_op_switch(struct function *fn, struct instruction *insn)
static void output_op_call(struct function *fn, struct instruction *insn)
{
LLVMValueRef target, func;
+ struct symbol *ctype;
int n_arg = 0, i;
struct pseudo *arg;
LLVMValueRef *args;
@@ -795,10 +796,13 @@ static void output_op_call(struct function *fn, struct instruction *insn)
n_arg = pseudo_list_size(insn->arguments);
args = calloc(n_arg, sizeof(LLVMValueRef));
+ PREPARE_PTR_LIST(insn->fntypes, ctype);
i = 0;
FOR_EACH_PTR(insn->arguments, arg) {
- args[i++] = pseudo_to_value(fn, NULL, arg);
+ NEXT_PTR_LIST(ctype);
+ args[i++] = pseudo_to_value(fn, ctype, arg);
} END_FOR_EACH_PTR(arg);
+ FINISH_PTR_LIST(ctype);
func = pseudo_to_value(fn, NULL, insn->func);
pseudo_name(insn->target, name);
diff --git a/validation/backend/call-variadic.c b/validation/backend/call-variadic.c
index 19afacee..b6e40644 100644
--- a/validation/backend/call-variadic.c
+++ b/validation/backend/call-variadic.c
@@ -11,7 +11,6 @@ int foo(const char *fmt, int a, long l, int *p)
/*
* check-name: call-variadic
* check-command: sparse-llvm-dis -m64 $file
- * check-known-to-fail
*
* check-output-start
; ModuleID = '<stdin>'