linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] sparse, llvm: Make 'sparsec' error handling more robust
@ 2011-11-18 15:30 Pekka Enberg
  2011-11-18 15:30 ` [PATCH 2/2] sparse, llvm: Function pointer code generation Pekka Enberg
  0 siblings, 1 reply; 2+ messages in thread
From: Pekka Enberg @ 2011-11-18 15:30 UTC (permalink / raw)
  To: linux-sparse; +Cc: Pekka Enberg, Christopher Li, Jeff Garzik, Linus Torvalds

Make 'sparsec' more robust against SIGSEGV in Sparse/LLVM code so that 'make
check' detects test breakage.

Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
---
 sparsec |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/sparsec b/sparsec
index 1e5c8bd..33e1a2b 100755
--- a/sparsec
+++ b/sparsec
@@ -2,6 +2,8 @@
 #
 # GCC compatible C compiler based on Sparse LLVM
 
+set +e
+
 SPARSEOPTS=""
 DIRNAME=`dirname $0`
 
@@ -27,9 +29,12 @@ while [ $# -gt 0 ]; do
 	shift
 done
 
+TMPLLVM=`mktemp -t tmp.XXXXXX`".llvm"
 TMPFILE=`mktemp -t tmp.XXXXXX`".o"
 
-$DIRNAME/sparse-llvm $SPARSEOPTS | llc | as -o $TMPFILE
+$DIRNAME/sparse-llvm $SPARSEOPTS > $TMPLLVM
+
+llc $TMPLLVM | as -o $TMPFILE
 
 if [ $NEED_LINK -eq 1 ]; then
 	if [ -z $OUTFILE ]; then
@@ -43,3 +48,5 @@ else
 	fi
 	mv $TMPFILE $OUTFILE
 fi
+
+rm -f $TMPLLVM
-- 
1.7.6.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] sparse, llvm: Function pointer code generation
  2011-11-18 15:30 [PATCH 1/2] sparse, llvm: Make 'sparsec' error handling more robust Pekka Enberg
@ 2011-11-18 15:30 ` Pekka Enberg
  0 siblings, 0 replies; 2+ messages in thread
From: Pekka Enberg @ 2011-11-18 15:30 UTC (permalink / raw)
  To: linux-sparse; +Cc: Pekka Enberg, Christopher Li, Jeff Garzik, Linus Torvalds

This patch implements support for function pointer types and function pointer
calls to the LLVM backend.

Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
---
 sparse-llvm.c                     |   54 +++++++++++++++++++++++++++++++++++-
 validation/backend/function-ptr.c |   11 +++++++
 2 files changed, 63 insertions(+), 2 deletions(-)
 create mode 100644 validation/backend/function-ptr.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 7f46c8a..c037e02 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -34,6 +34,46 @@ static inline bool symbol_is_fp_type(struct symbol *sym)
 
 static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym);
 
+static LLVMTypeRef func_return_type(LLVMModuleRef module, struct symbol *sym)
+{
+	return symbol_type(module, sym->ctype.base_type);
+}
+
+static LLVMTypeRef sym_func_type(LLVMModuleRef module, struct symbol *sym)
+{
+	LLVMTypeRef *arg_type;
+	LLVMTypeRef func_type;
+	LLVMTypeRef ret_type;
+	struct symbol *arg;
+	int n_arg = 0;
+
+	/* to avoid strangeness with varargs [for now], we build
+	 * the function and type anew, for each call.  This
+	 * is probably wrong.  We should look up the
+	 * symbol declaration info.
+	 */
+
+	ret_type = func_return_type(module, sym);
+
+	/* count args, build argument type information */
+	FOR_EACH_PTR(sym->arguments, arg) {
+		n_arg++;
+	} END_FOR_EACH_PTR(arg);
+
+	arg_type = calloc(n_arg, sizeof(LLVMTypeRef));
+
+	int idx = 0;
+	FOR_EACH_PTR(sym->arguments, arg) {
+		struct symbol *arg_sym = arg->ctype.base_type;
+
+		arg_type[idx++] = symbol_type(module, arg_sym);
+	} END_FOR_EACH_PTR(arg);
+	func_type = LLVMFunctionType(ret_type, arg_type, n_arg,
+				     /* varargs? */ 0);
+
+	return func_type;
+}
+
 static LLVMTypeRef sym_array_type(LLVMModuleRef module, struct symbol *sym)
 {
 	LLVMTypeRef elem_type;
@@ -172,6 +212,9 @@ static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym)
 	case SYM_ARRAY:
 		ret = sym_array_type(module, sym);
 		break;
+	case SYM_FN:
+		ret = sym_func_type(module, sym);
+		break;
 	default:
 		assert(0);
 	}
@@ -638,7 +681,10 @@ static LLVMTypeRef get_func_type(struct function *fn, struct instruction *insn)
 	int n_arg = 0;
 	LLVMTypeRef *arg_type;
 
-	sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
+	if (sym->ident)
+		sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
+	else
+		sprintf(buffer, "<anon sym %p>", sym);
 
 	/* VERIFY: is this correct, for functions? */
 	func_type = LLVMGetTypeByName(fn->module, buffer);
@@ -682,7 +728,11 @@ static LLVMValueRef get_function(struct function *fn, struct instruction *insn)
 	LLVMValueRef func;
 	struct llfunc *f;
 
-	sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
+	if (sym->ident)
+		sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
+	else
+		sprintf(buffer, "<anon sym %p>", sym);
+
 
 	/* search for pre-built function type definition */
 	FOR_EACH_PTR(mi.llfunc_list, f) {
diff --git a/validation/backend/function-ptr.c b/validation/backend/function-ptr.c
new file mode 100644
index 0000000..fc022b3
--- /dev/null
+++ b/validation/backend/function-ptr.c
@@ -0,0 +1,11 @@
+typedef int (*fn_t)(int x, int y);
+
+static int run(fn_t fn, int x, int y)
+{
+	return fn(x, y);
+}
+
+/*
+ * check-name: Function pointer code generation
+ * check-command: ./sparsec -c $file -o tmp.o
+ */
-- 
1.7.6.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-11-18 15:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-18 15:30 [PATCH 1/2] sparse, llvm: Make 'sparsec' error handling more robust Pekka Enberg
2011-11-18 15:30 ` [PATCH 2/2] sparse, llvm: Function pointer code generation Pekka Enberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).