Re: Casting away noderef and address spaces?

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

 



On Mon, 2008-12-22 at 17:25 -0800, Christopher Li wrote:

> Do you want to resend your change which revert the context changes?
> Make it base on Josh's git's tree and I will merge your changes in my
> branch.

Below. Or I can give it to you in git if you prefer. I still think we
should redo this in some form so that annotations with different
contexts can work properly, but I don't have time to take care of it
right now.

> It will take me a while to get up to speed with the git goodness.
> I will start with merging Alexey's resend patches.

Mind you, he sent a few of my patches, so ignore those.

johannes

>From ca95b62edf1600a2b55ed9ca0515d049807a84fc Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>
Date: Tue, 23 Dec 2008 10:53:19 +0100
Subject: [PATCH] Revert context tracking code

---
 inline.c                       |   12 +-
 linearize.c                    |   31 ++-
 linearize.h                    |    7 +-
 parse.c                        |  134 +---------
 parse.h                        |    3 +-
 sparse.1                       |   41 +---
 sparse.c                       |  424 ++++---------------------------
 symbol.h                       |    3 +-
 validation/context-dynamic.c   |  171 -------------
 validation/context-named.c     |  553 ----------------------------------------
 validation/context-statement.c |   69 -----
 validation/context.c           |  114 +-------
 12 files changed, 107 insertions(+), 1455 deletions(-)
 delete mode 100644 validation/context-dynamic.c
 delete mode 100644 validation/context-named.c
 delete mode 100644 validation/context-statement.c

diff --git a/inline.c b/inline.c
index 09d176a..860c0ee 100644
--- a/inline.c
+++ b/inline.c
@@ -331,18 +331,10 @@ static struct statement *copy_one_statement(struct statement *stmt)
 	case STMT_CONTEXT:
 	case STMT_EXPRESSION: {
 		struct expression *expr = copy_expression(stmt->expression);
-		struct statement *newstmt;
 		if (expr == stmt->expression)
 			break;
-		newstmt = dup_statement(stmt);
-		newstmt->expression = expr;
-		if (stmt->required) {
-			expr = copy_expression(stmt->required);
-			if (expr == stmt->required)
-				break;
-			newstmt->required = expr;
-		}
-		stmt = newstmt;
+		stmt = dup_statement(stmt);
+		stmt->expression = expr;
 		break;
 	}
 	case STMT_RANGE: {
diff --git a/linearize.c b/linearize.c
index 526a710..1a19214 100644
--- a/linearize.c
+++ b/linearize.c
@@ -68,6 +68,7 @@ static struct entrypoint *alloc_entrypoint(void)
 static struct basic_block *alloc_basic_block(struct entrypoint *ep, struct position pos)
 {
 	struct basic_block *bb = __alloc_basic_block(0);
+	bb->context = -1;
 	bb->pos = pos;
 	bb->ep = ep;
 	return bb;
@@ -440,7 +441,7 @@ const char *show_instruction(struct instruction *insn)
 		break;
 
 	case OP_CONTEXT:
-		buf += sprintf(buf, "%s%d,%d", "", insn->increment, insn->inc_false);
+		buf += sprintf(buf, "%s%d", insn->check ? "check: " : "", insn->increment);
 		break;
 	case OP_RANGE:
 		buf += sprintf(buf, "%s between %s..%s", show_pseudo(insn->src1), show_pseudo(insn->src2), show_pseudo(insn->src3));
@@ -1234,12 +1235,22 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
 		FOR_EACH_PTR(ctype->contexts, context) {
 			int in = context->in;
 			int out = context->out;
-
-			if (out - in || context->out_false - in) {
+			int check = 0;
+			int context_diff;
+			if (in < 0) {
+				check = 1;
+				in = 0;
+			}
+			if (out < 0) {
+				check = 0;
+				out = 0;
+			}
+			context_diff = out - in;
+			if (check || context_diff) {
 				insn = alloc_instruction(OP_CONTEXT, 0);
-				insn->increment = out - in;
+				insn->increment = context_diff;
+				insn->check = check;
 				insn->context_expr = context->context;
-				insn->inc_false = context->out_false - in;
 				add_one_insn(ep, insn);
 			}
 		} END_FOR_EACH_PTR(context);
@@ -1674,16 +1685,6 @@ static pseudo_t linearize_context(struct entrypoint *ep, struct statement *stmt)
 		value = expr->value;
 
 	insn->increment = value;
-	insn->inc_false = value;
-
-	expr = stmt->required;
-	value = 0;
-
-	if (expr && expr->type == EXPR_VALUE)
-		value = expr->value;
-
-	insn->required = value;
-
 	insn->context_expr = stmt->context;
 	add_one_insn(ep, insn);
 	return VOID;
diff --git a/linearize.h b/linearize.h
index 0c5e4ef..2205082 100644
--- a/linearize.h
+++ b/linearize.h
@@ -117,7 +117,8 @@ struct instruction {
 			struct pseudo_list *arguments;
 		};
 		struct /* context */ {
-			int increment, required, inc_false;
+			int increment;
+			int check;
 			struct expression *context_expr;
 		};
 		struct /* asm */ {
@@ -220,13 +221,11 @@ enum opcode {
 
 struct basic_block_list;
 struct instruction_list;
-struct context_list_list;
 
 struct basic_block {
 	struct position pos;
 	unsigned long generation;
-	int context_check_recursion;
-	struct context_list_list *checked_contexts;
+	int context;
 	struct entrypoint *ep;
 	struct basic_block_list *parents; /* sources */
 	struct basic_block_list *children; /* destinations */
diff --git a/parse.c b/parse.c
index eb31871..a78012a 100644
--- a/parse.c
+++ b/parse.c
@@ -64,8 +64,6 @@ static struct token *attribute_address_space(struct token *token, struct symbol
 static struct token *attribute_aligned(struct token *token, struct symbol *attr, struct ctype *ctype);
 static struct token *attribute_mode(struct token *token, struct symbol *attr, struct ctype *ctype);
 static struct token *attribute_context(struct token *token, struct symbol *attr, struct ctype *ctype);
-static struct token *attribute_conditional_context(struct token *token, struct symbol *attr, struct ctype *ctype);
-static struct token *attribute_exact_context(struct token *token, struct symbol *attr, struct ctype *ctype);
 static struct token *attribute_transparent_union(struct token *token, struct symbol *attr, struct ctype *ctype);
 static struct token *ignore_attribute(struct token *token, struct symbol *attr, struct ctype *ctype);
 
@@ -184,14 +182,6 @@ static struct symbol_op context_op = {
 	.attribute = attribute_context,
 };
 
-static struct symbol_op conditional_context_op = {
-	.attribute = attribute_conditional_context,
-};
-
-static struct symbol_op exact_context_op = {
-	.attribute = attribute_exact_context,
-};
-
 static struct symbol_op transparent_union_op = {
 	.attribute = attribute_transparent_union,
 };
@@ -273,8 +263,6 @@ static struct init_keyword {
 	{ "address_space",NS_KEYWORD,	.op = &address_space_op },
 	{ "mode",	NS_KEYWORD,	.op = &mode_op },
 	{ "context",	NS_KEYWORD,	.op = &context_op },
-	{ "conditional_context",	NS_KEYWORD,	.op = &conditional_context_op },
-	{ "exact_context",	NS_KEYWORD,	.op = &exact_context_op },
 	{ "__transparent_union__",	NS_KEYWORD,	.op = &transparent_union_op },
 
 	{ "__mode__",	NS_KEYWORD,	.op = &mode_op },
@@ -875,7 +863,7 @@ static struct token *attribute_mode(struct token *token, struct symbol *attr, st
 	return token;
 }
 
-static struct token *_attribute_context(struct token *token, struct symbol *attr, struct ctype *ctype, int exact)
+static struct token *attribute_context(struct token *token, struct symbol *attr, struct ctype *ctype)
 {
 	struct context *context = alloc_context();
 	struct expression *args[3];
@@ -889,8 +877,6 @@ static struct token *_attribute_context(struct token *token, struct symbol *attr
 			break;
 		if (argc < 3)
 			args[argc++] = expr;
-		else
-			argc++;
 		if (!match_op(token, ','))
 			break;
 		token = token->next;
@@ -912,14 +898,8 @@ static struct token *_attribute_context(struct token *token, struct symbol *attr
 		context->in = get_expression_value(args[1]);
 		context->out = get_expression_value(args[2]);
 		break;
-	default:
-		sparse_error(token->pos, "too many arguments to context attribute");
-		break;
 	}
 
-	context->exact = exact;
-	context->out_false = context->out;
-
 	if (argc)
 		add_ptr_list(&ctype->contexts, context);
 
@@ -927,61 +907,6 @@ static struct token *_attribute_context(struct token *token, struct symbol *attr
 	return token;
 }
 
-static struct token *attribute_context(struct token *token, struct symbol *attr, struct ctype *ctype)
-{
-	return _attribute_context(token, attr, ctype, 0);
-}
-
-static struct token *attribute_exact_context(struct token *token, struct symbol *attr, struct ctype *ctype)
-{
-	return _attribute_context(token, attr, ctype, 1);
-}
-
-static struct token *attribute_conditional_context(struct token *token, struct symbol *attr, struct ctype *ctype)
-{
-	struct context *context = alloc_context();
-	struct expression *args[4];
-	int argc = 0;
-
-	token = expect(token, '(', "after conditional_context attribute");
-	while (!match_op(token, ')')) {
-		struct expression *expr = NULL;
-		token = conditional_expression(token, &expr);
-		if (!expr)
-			break;
-		if (argc < 4)
-			args[argc++] = expr;
-		else
-			argc++;
-		if (!match_op(token, ','))
-			break;
-		token = token->next;
-	}
-
-	switch(argc) {
-	case 3:
-		context->in = get_expression_value(args[0]);
-		context->out = get_expression_value(args[1]);
-		context->out_false = get_expression_value(args[2]);
-		break;
-	case 4:
-		context->context = args[0];
-		context->in = get_expression_value(args[1]);
-		context->out = get_expression_value(args[2]);
-		context->out_false = get_expression_value(args[3]);
-		break;
-	default:
-		sparse_error(token->pos, "invalid number of arguments to conditional_context attribute");
-		break;
-	}
-
-	if (argc)
-		add_ptr_list(&ctype->contexts, context);
-
-	token = expect(token, ')', "after conditional_context attribute");
-	return token;
-}
-
 static struct token *attribute_transparent_union(struct token *token, struct symbol *attr, struct ctype *ctype)
 {
 	if (Wtransparent_union)
@@ -1813,56 +1738,17 @@ static struct token *parse_goto_statement(struct token *token, struct statement
 
 static struct token *parse_context_statement(struct token *token, struct statement *stmt)
 {
-	struct expression *args[3];
-	int argc = 0;
-
 	stmt->type = STMT_CONTEXT;
-	token = token->next;
-	token = expect(token, '(', "after __context__ statement");
-	while (!match_op(token, ')')) {
-		struct expression *expr = NULL;
-		token = conditional_expression(token, &expr);
-		if (!expr)
-			break;
-		if (argc < 3)
-			args[argc++] = expr;
-		else
-			argc++;
-		if (!match_op(token, ','))
-			break;
-		token = token->next;
-	}
-
-	stmt->expression = args[0];
-	stmt->context = NULL;
-
-	switch (argc) {
-	case 0:
-		sparse_error(token->pos, "__context__ statement needs argument(s)");
-		return token;
-	case 1:
-		/* already done */
-		break;
-	case 2:
-		if (args[0]->type != STMT_EXPRESSION) {
-			stmt->context = args[0];
-			stmt->expression = args[1];
-		} else {
-			stmt->expression = args[0];
-			stmt->required = args[1];
-		}
-		break;
-	case 3:
-		stmt->context = args[0];
-		stmt->expression = args[1];
-		stmt->required = args[2];
-		break;
-	default:
-		sparse_error(token->pos, "too many arguments for __context__ statement");
-		return token->next;
+	token = parse_expression(token->next, &stmt->expression);
+	if(stmt->expression->type == EXPR_PREOP
+	   && stmt->expression->op == '('
+	   && stmt->expression->unop->type == EXPR_COMMA) {
+		struct expression *expr;
+		expr = stmt->expression->unop;
+		stmt->context = expr->left;
+		stmt->expression = expr->right;
 	}
-
-	return expect(token, ')', "at end of __context__");
+	return expect(token, ';', "at end of statement");
 }
 
 static struct token *parse_range_statement(struct token *token, struct statement *stmt)
diff --git a/parse.h b/parse.h
index a2b9aa3..609910f 100644
--- a/parse.h
+++ b/parse.h
@@ -39,10 +39,9 @@ struct statement {
 			struct symbol *label;
 			struct statement *label_statement;
 		};
-		struct { /* __context__ */
+		struct {
 			struct expression *expression;
 			struct expression *context;
-			struct expression *required;
 		};
 		struct /* return_statement */ {
 			struct expression *ret_value;
diff --git a/sparse.1 b/sparse.1
index 92a1cae..c44e3a5 100644
--- a/sparse.1
+++ b/sparse.1
@@ -73,43 +73,20 @@ Warn about potential errors in synchronization or other delimited contexts.
 Sparse supports several means of designating functions or statements that
 delimit contexts, such as synchronization.  Functions with the extended
 attribute
-.BI __attribute__((context( [expression ,] in_context , out_context ))
-require the context \fIexpression\fR (for instance, a lock) to have at least the value
+.BI __attribute__((context( expression , in_context , out_context ))
+require the context \fIexpression\fR (for instance, a lock) to have the value
 \fIin_context\fR (a constant nonnegative integer) when called, and return with
-the value adjusted by \fIout_context - in_context\fR (where
-\fIout_context\fR is a constant nonnegative integer).  To change the value
-of a context (for example in macros), use the statement
-.BI __context__( [expression , ]adjust_value[ , required] )
-where \fIadjust_value\fR is a constant integer and \fIrequired\fR is a
-constant nonnegative integer. Not giving \fIrequired\fR is equivalent to
-giving zero and means that the statement does not need the context as a
-precondition, when given it means that the context must at least have the
-value of \fIrequired\fR.
-
-To indicate that a function requires
-.BI exactly
-a certain lock context (not "at least" as above), use the form
-.BI __attribute__((exact_context( [expression ,] in_context , out_context ))
-There currently is no corresponding
-.BI __exact_context__( [expression , ]adjust_value[ , required] )
-statement.
-
-To indicate that a certain function acquires a context depending on its
-return value, use
-.BI __attribute__((conditional_context( [expression ,] in_context , out_success , out_failure ))
-where \fIout_success\fR and \fIout_failure\fR indicate the context change
-done depending on success (non-zero) or failure (zero) return of the
-function. Note that currently, using this attribute on a function means that
-the function itself won't be checked for context handling at all. See the
-testsuite for examples.
-
-Sparse will warn when it sees a function change a
-context without indicating this with a \fBcontext\fR or \fBexact_context\fR attribute, either by
+the value \fIout_context\fR (a constant nonnegative integer).  For APIs
+defined via macros, use the statement form
+.BI __context__( expression , in_value , out_value )
+in the body of the macro.
+
+With \fB-Wcontext\fR Sparse will warn when it sees a function change the
+context without indicating this with a \fBcontext\fR attribute, either by
 decreasing a context below zero (such as by releasing a lock without acquiring
 it), or returning with a changed context (such as by acquiring a lock without
 releasing it).  Sparse will also warn about blocks of code which may
-potentially execute with different contexts and about functions that are
-executed without a lock they require.
+potentially execute with different contexts.
 
 Sparse issues these warnings by default.  To turn them off, use
 \fB\-Wno\-context\fR.
diff --git a/sparse.c b/sparse.c
index 785a6f6..4026ba7 100644
--- a/sparse.c
+++ b/sparse.c
@@ -24,389 +24,77 @@
 #include "expression.h"
 #include "linearize.h"
 
-struct context_check {
-	int val, val_false;
-	char name[32];
-};
-
-DECLARE_ALLOCATOR(context_check);
-DECLARE_PTR_LIST(context_check_list, struct context_check);
-DECLARE_PTR_LIST(context_list_list, struct context_check_list);
-ALLOCATOR(context_check, "context check list");
-
-static const char *unnamed_context = "<unnamed>";
-
-static const char *context_name(struct context *context)
-{
-	if (context->context && context->context->symbol_name)
-		return show_ident(context->context->symbol_name);
-	return unnamed_context;
-}
-
-static void context_add(struct context_check_list **ccl, const char *name,
-			int offs, int offs_false)
-{
-	struct context_check *check, *found = NULL;
-
-	FOR_EACH_PTR(*ccl, check) {
-		if (strcmp(name, check->name))
-			continue;
-		found = check;
-		break;
-	} END_FOR_EACH_PTR(check);
-
-	if (!found) {
-		found = __alloc_context_check(0);
-		strncpy(found->name, name, sizeof(found->name));
-		found->name[sizeof(found->name) - 1] = '\0';
-		add_ptr_list(ccl, found);
-	}
-	found->val += offs;
-	found->val_false += offs_false;
-}
-
-static int context_list_has(struct context_check_list *ccl,
-			    struct context_check *c)
+static int context_increase(struct basic_block *bb, int entry)
 {
-	struct context_check *check;
+	int sum = 0;
+	struct instruction *insn;
 
-	FOR_EACH_PTR(ccl, check) {
-		if (strcmp(c->name, check->name))
+	FOR_EACH_PTR(bb->insns, insn) {
+		int val;
+		if (insn->opcode != OP_CONTEXT)
 			continue;
-		return check->val == c->val &&
-		       check->val_false == c->val_false;
-	} END_FOR_EACH_PTR(check);
-
-	/* not found is equal to 0 */
-	return c->val == 0 && c->val_false == 0;
-}
-
-static int context_lists_equal(struct context_check_list *ccl1,
-			       struct context_check_list *ccl2)
-{
-	struct context_check *check;
-
-	/* can be optimised... */
-
-	FOR_EACH_PTR(ccl1, check) {
-		if (!context_list_has(ccl2, check))
-			return 0;
-	} END_FOR_EACH_PTR(check);
-
-	FOR_EACH_PTR(ccl2, check) {
-		if (!context_list_has(ccl1, check))
-			return 0;
-	} END_FOR_EACH_PTR(check);
-
-	return 1;
-}
-
-static struct context_check_list *checked_copy(struct context_check_list *ccl)
-{
-	struct context_check_list *result = NULL;
-	struct context_check *c;
-
-	FOR_EACH_PTR(ccl, c) {
-		context_add(&result, c->name, c->val_false, c->val_false);
-	} END_FOR_EACH_PTR(c);
-
-	return result;
-}
-
-#define IMBALANCE_IN "context imbalance in '%s': "
-#define DEFAULT_CONTEXT_DESCR "   default context: "
-
-static void get_context_string(char **buf, const char **name)
-{
-	if (strcmp(*name, unnamed_context)) {
-		*buf = malloc(strlen(*name) + 16);
-		sprintf(*buf, "   context '%s': ", *name);
-		*name = *buf;
-	} else {
-		*name = DEFAULT_CONTEXT_DESCR;
-		*buf = NULL;
-	}
-}
-
-static int context_list_check(struct entrypoint *ep, struct position pos,
-			      struct context_check_list *ccl_cur,
-			      struct context_check_list *ccl_target)
-{
-	struct context_check *c1, *c2;
-	int cur, tgt;
-	const char *name;
-	char *buf;
-
-	/* make sure the loop below checks all */
-	FOR_EACH_PTR(ccl_target, c1) {
-		context_add(&ccl_cur, c1->name, 0, 0);
-	} END_FOR_EACH_PTR(c1);
-
-	FOR_EACH_PTR(ccl_cur, c1) {
-		cur = c1->val;
-		tgt = 0;
-
-		FOR_EACH_PTR(ccl_target, c2) {
-			if (strcmp(c2->name, c1->name))
+		val = insn->increment;
+		if (insn->check) {
+			int current = sum + entry;
+			if (!val) {
+				if (!current)
+					continue;
+			} else if (current >= val)
 				continue;
-			tgt = c2->val;
-			break;
-		} END_FOR_EACH_PTR(c2);
-
-		if (cur == tgt || !Wcontext)
+			warning(insn->pos, "context check failure");
 			continue;
-
-		if (cur > tgt)
-			warning(pos, IMBALANCE_IN "wrong count at exit",
-				show_ident(ep->name->ident));
-		else if (cur < tgt)
-			warning(pos, IMBALANCE_IN "unexpected unlock",
-				show_ident(ep->name->ident));
-
-		name = c1->name;
-		get_context_string(&buf, &name);
-
-		info(pos, "%swanted %d, got %d",
-		     name, tgt, cur);
-
-		free(buf);
-
-		return -1;
-	} END_FOR_EACH_PTR(c1);
-
-	return 0;
-}
-
-static int handle_call(struct entrypoint *ep, struct basic_block *bb,
-		       struct instruction *insn,
-		       struct context_check_list *combined)
-{
-	struct context *ctx;
-	struct context_check *c;
-	const char *name, *call, *cmp;
-	char *buf;
-	int val, ok;
-
-	if (!insn->func || !insn->func->sym ||
-	    insn->func->type != PSEUDO_SYM)
-		return 0;
-
-	/*
-	 * Check all contexts the function wants.
-	 */
-	FOR_EACH_PTR(insn->func->sym->ctype.contexts, ctx) {
-		name = context_name(ctx);
-		val = 0;
-
-		FOR_EACH_PTR(combined, c) {
-			if (strcmp(c->name, name) == 0) {
-				val = c->val;
-				break;
-			}
-		} END_FOR_EACH_PTR(c);
-
-		if (ctx->exact) {
-			ok = ctx->in == val;
-			cmp = "";
-		} else {
-			ok = ctx->in <= val;
-			cmp = ">= ";
-		}
-
-		if (!ok && Wcontext) {
-			get_context_string(&buf, &name);
-			call = strdup(show_ident(insn->func->ident));
-
-			warning(insn->pos, "context problem in '%s': "
-				"'%s' expected different context",
-				show_ident(ep->name->ident), call);
-
-			info(insn->pos, "%swanted %s%d, got %d",
-			     name, cmp, ctx->in, val);
-
-			free((void *)call);
-			free(buf);
-
-			return -1;
 		}
-	} END_FOR_EACH_PTR (ctx);
-
-	return 0;
+		sum += val;
+	} END_FOR_EACH_PTR(insn);
+	return sum;
 }
 
-static int handle_context(struct entrypoint *ep, struct basic_block *bb,
-			  struct instruction *insn,
-			  struct context_check_list **combined)
+static int imbalance(struct entrypoint *ep, struct basic_block *bb, int entry, int exit, const char *why)
 {
-	struct context_check *c;
-	const char *name;
-	char *buf;
-	int val, ok;
-
-	val = 0;
-
-	name = unnamed_context;
-	if (insn->context_expr)
-		name = show_ident(insn->context_expr->symbol_name);
-
-	FOR_EACH_PTR(*combined, c) {
-		if (strcmp(c->name, name) == 0) {
-			val = c->val;
-			break;
-		}
-	} END_FOR_EACH_PTR(c);
-
-	ok = insn->required <= val;
-
-	if (!ok && Wcontext) {
-		get_context_string(&buf, &name);
-
-		warning(insn->pos,
-			IMBALANCE_IN
-			"__context__ statement expected different context",
-			show_ident(ep->name->ident));
-
-		info(insn->pos, "%swanted >= %d, got %d",
-		     name, insn->required, val);
-
-		free(buf);
-		return -1;
+	if (Wcontext) {
+		struct symbol *sym = ep->name;
+		warning(bb->pos, "context imbalance in '%s' - %s", show_ident(sym->ident), why);
 	}
-
-	context_add(combined, name, insn->increment, insn->inc_false);
-
-	return 0;
+	return -1;
 }
 
-static int check_bb_context(struct entrypoint *ep, struct basic_block *bb,
-			    struct context_check_list *ccl_in,
-			    struct context_check_list *ccl_target,
-			    int in_false)
+static int check_bb_context(struct entrypoint *ep, struct basic_block *bb, int entry, int exit);
+
+static int check_children(struct entrypoint *ep, struct basic_block *bb, int entry, int exit)
 {
-	struct context_check_list *combined = NULL, *done;
-	struct context_check *c;
 	struct instruction *insn;
-	struct multijmp *mj;
-	int err = -1;
-
-	/*
-	 * Recurse in once to catch bad loops.
-	 */
-	if (bb->context_check_recursion > 1)
-		return 0;
-	bb->context_check_recursion++;
-
-	/*
-	 * Abort if we have already checked this block out of the same context.
-	 */
-	FOR_EACH_PTR(bb->checked_contexts, done) {
-		if (context_lists_equal(done, ccl_in))
-			return 0;
-	} END_FOR_EACH_PTR(done);
-
-	/*
-	 * We're starting with a completely new local list of contexts, so
-	 * initialise it according to what we got from the parent block.
-	 * That may use either the 'false' or the 'true' part of the context
-	 * for the conditional_context() attribute.
-	 */
-	FOR_EACH_PTR(ccl_in, c) {
-		if (in_false)
-			context_add(&combined, c->name, c->val_false, c->val_false);
-		else
-			context_add(&combined, c->name, c->val, c->val);
-	} END_FOR_EACH_PTR(c);
-
-	/* Add the new context to the list of already-checked contexts */
-	done = checked_copy(combined);
-	add_ptr_list(&bb->checked_contexts, done);
-
-	/*
-	 * Now walk the instructions for this block, recursing into any
-	 * instructions that have children. We need to have the right
-	 * order so we cannot iterate bb->children instead.
-	 */
-	FOR_EACH_PTR(bb->insns, insn) {
-		switch (insn->opcode) {
-		case OP_INLINED_CALL:
-		case OP_CALL:
-			if (handle_call(ep, bb, insn, combined))
-				goto out;
-			break;
-		case OP_CONTEXT:
-			if (handle_context(ep, bb, insn, &combined))
-				goto out;
-			break;
-		case OP_BR:
-			if (insn->bb_true)
-				if (check_bb_context(ep, insn->bb_true,
-						     combined, ccl_target, 0))
-					goto out;
-			if (insn->bb_false)
-				if (check_bb_context(ep, insn->bb_false,
-						     combined, ccl_target, 1))
-					goto out;
-			break;
-		case OP_SWITCH:
-		case OP_COMPUTEDGOTO:
-			FOR_EACH_PTR(insn->multijmp_list, mj) {
-				if (check_bb_context(ep, mj->target,
-					             combined, ccl_target, 0))
-					goto out;
-			} END_FOR_EACH_PTR(mj);
-			break;
-		}
-	} END_FOR_EACH_PTR(insn);
+	struct basic_block *child;
 
 	insn = last_instruction(bb->insns);
 	if (!insn)
-		goto out_good;
-
-	if (insn->opcode == OP_RET) {
-		err = context_list_check(ep, insn->pos, combined, ccl_target);
-		goto out;
-	}
+		return 0;
+	if (insn->opcode == OP_RET)
+		return entry != exit ? imbalance(ep, bb, entry, exit, "wrong count at exit") : 0;
 
- out_good:
-	err = 0;
- out:
-	/* contents will be freed once we return out of recursion */
-	free_ptr_list(&combined);
-	bb->context_check_recursion--;
-	return err;
+	FOR_EACH_PTR(bb->children, child) {
+		if (check_bb_context(ep, child, entry, exit))
+			return -1;
+	} END_FOR_EACH_PTR(child);
+	return 0;
 }
 
-static void free_bb_context_lists(struct basic_block *bb)
+static int check_bb_context(struct entrypoint *ep, struct basic_block *bb, int entry, int exit)
 {
-	struct context_check_list *done;
-	struct instruction *insn;
-	struct multijmp *mj;
-
-	if (!bb->checked_contexts)
-		return;
+	if (!bb)
+		return 0;
+	if (bb->context == entry)
+		return 0;
 
-	FOR_EACH_PTR(bb->checked_contexts, done) {
-		free_ptr_list(&done);
-	} END_FOR_EACH_PTR(done);
+	/* Now that's not good.. */
+	if (bb->context >= 0)
+		return imbalance(ep, bb, entry, bb->context, "different lock contexts for basic block");
 
-	free_ptr_list(&bb->checked_contexts);
+	bb->context = entry;
+	entry += context_increase(bb, entry);
+	if (entry < 0)
+		return imbalance(ep, bb, entry, exit, "unexpected unlock");
 
-	FOR_EACH_PTR(bb->insns, insn) {
-		switch (insn->opcode) {
-		case OP_BR:
-			if (insn->bb_true)
-				free_bb_context_lists(insn->bb_true);
-			if (insn->bb_false)
-				free_bb_context_lists(insn->bb_false);
-			break;
-		case OP_SWITCH:
-		case OP_COMPUTEDGOTO:
-			FOR_EACH_PTR(insn->multijmp_list, mj) {
-				free_bb_context_lists(mj->target);
-			} END_FOR_EACH_PTR(mj);
-			break;
-		}
-	} END_FOR_EACH_PTR(insn);
+	return check_children(ep, bb, entry, exit);
 }
 
 static void check_cast_instruction(struct instruction *insn)
@@ -547,7 +235,7 @@ static void check_context(struct entrypoint *ep)
 {
 	struct symbol *sym = ep->name;
 	struct context *context;
-	struct context_check_list *ccl_in = NULL, *ccl_target = NULL;
+	unsigned int in_context = 0, out_context = 0;
 
 	if (Wuninitialized && verbose && ep->entry->bb->needs) {
 		pseudo_t pseudo;
@@ -561,20 +249,10 @@ static void check_context(struct entrypoint *ep)
 	check_instructions(ep);
 
 	FOR_EACH_PTR(sym->ctype.contexts, context) {
-		const char *name = context_name(context);
-
-		context_add(&ccl_in, name, context->in, context->in);
-		context_add(&ccl_target, name, context->out, context->out_false);
-		/* we don't currently check the body of trylock functions */
-		if (context->out != context->out_false)
-			return;
+		in_context += context->in;
+		out_context += context->out;
 	} END_FOR_EACH_PTR(context);
-
-	check_bb_context(ep, ep->entry->bb, ccl_in, ccl_target, 0);
-	free_ptr_list(&ccl_in);
-	free_ptr_list(&ccl_target);
-	free_bb_context_lists(ep->entry->bb);
-	clear_context_check_alloc();
+	check_bb_context(ep, ep->entry->bb, in_context, out_context);
 }
 
 static void check_symbols(struct symbol_list *list)
diff --git a/symbol.h b/symbol.h
index c4d7f28..4155b46 100644
--- a/symbol.h
+++ b/symbol.h
@@ -71,8 +71,7 @@ enum keyword {
 
 struct context {
 	struct expression *context;
-	unsigned int in, out, out_false;
-	int exact;
+	unsigned int in, out;
 };
 
 extern struct context *alloc_context(void);
diff --git a/validation/context-dynamic.c b/validation/context-dynamic.c
deleted file mode 100644
index 5e172f0..0000000
--- a/validation/context-dynamic.c
+++ /dev/null
@@ -1,171 +0,0 @@
-static void a(void) __attribute__ ((context(A, 0, 1)))
-{
-    __context__(A, 1);
-}
-
-static void r(void) __attribute__ ((context(A, 1, 0)))
-{
-    __context__(A, -1);
-}
-
-extern int condition, condition2;
-
-static int tl(void) __attribute__ ((conditional_context(A, 0, 1, 0)))
-{
-    if (condition) {
-        a();
-        return 1;
-    }
-    return 0;
-}
-
-static int tl2(void) __attribute__ ((conditional_context(A, 0, 0, 1)))
-{
-    if (condition) {
-        a();
-        return 1;
-    }
-    return 0;
-}
-
-static int dummy(void)
-{
-    return condition + condition2;
-}
-
-static int good_trylock1(void)
-{
-    if (tl()) {
-        r();
-    }
-}
-
-static int good_trylock2(void)
-{
-    if (tl()) {
-        r();
-    }
-
-    if (tl()) {
-        r();
-    }
-}
-static int good_trylock3(void)
-{
-    a();
-    if (tl()) {
-        r();
-    }
-    r();
-    if (tl()) {
-        r();
-    }
-}
-
-static int good_trylock4(void)
-{
-    a();
-    if (tl()) {
-        r();
-    }
-    if (tl()) {
-        r();
-    }
-    r();
-}
-
-static void bad_trylock1(void)
-{
-    a();
-    if (dummy()) {
-        r();
-    }
-    r();
-}
-
-static int good_trylock5(void)
-{
-    if (!tl2()) {
-        r();
-    }
-}
-
-static int good_trylock6(void)
-{
-    if (!tl2()) {
-        r();
-    }
-
-    if (!tl2()) {
-        r();
-    }
-}
-static int good_trylock7(void)
-{
-    a();
-    if (!tl2()) {
-        r();
-    }
-    r();
-    if (!tl2()) {
-        r();
-    }
-}
-
-static int good_trylock8(void)
-{
-    a();
-    if (!tl2()) {
-        r();
-    }
-    if (!tl2()) {
-        r();
-    }
-    r();
-}
-
-static void bad_trylock2(void)
-{
-    a();
-    if (!dummy()) {
-        r();
-    }
-    r();
-}
-
-static int good_switch(void)
-{
-    switch (condition) {
-    case 1:
-        a();
-        break;
-    case 2:
-        a();
-        break;
-    case 3:
-        a();
-        break;
-    default:
-        a();
-    }
-    r();
-}
-
-static void bad_lock1(void)
-{
-    r();
-    a();
-}
-
-/*
- * check-name: Check -Wcontext with lock trylocks
- *
- * check-error-start
-context-dynamic.c:83:6: warning: context problem in 'bad_trylock1': 'r' expected different context
-context-dynamic.c:83:6:    context 'A': wanted >= 1, got 0
-context-dynamic.c:133:6: warning: context problem in 'bad_trylock2': 'r' expected different context
-context-dynamic.c:133:6:    context 'A': wanted >= 1, got 0
-context-dynamic.c:156:6: warning: context problem in 'bad_lock1': 'r' expected different context
-context-dynamic.c:156:6:    context 'A': wanted >= 1, got 0
- * check-error-end
- */
diff --git a/validation/context-named.c b/validation/context-named.c
deleted file mode 100644
index 58310e9..0000000
--- a/validation/context-named.c
+++ /dev/null
@@ -1,553 +0,0 @@
-static void a(void) __attribute__((context(TEST,0,1)))
-{
-	__context__(TEST,1);
-}
-
-static void r(void) __attribute__((context(TEST,1,0)))
-{
-	__context__(TEST,-1,1);
-}
-
-static void a2(void) __attribute__((context(TEST2,0,1)))
-{
-	__context__(TEST2,1);
-}
-
-static void r2(void) __attribute__((context(TEST2,1,0)))
-{
-	__context__(TEST2,-1,1);
-}
-
-#define check_test2() __context__(TEST2,0,1)
-
-static void good_paired1(void)
-{
-	a();
-	a2();
-	r();
-	r2();
-}
-
-static void good_paired2(void)
-{
-	a();
-	r();
-	a();
-	r();
-	a2();
-	r2();
-}
-
-static void good_paired3(void)
-{
-	a();
-	a();
-	r();
-	r();
-	a2();
-	a2();
-	r2();
-	r2();
-}
-
-static void good_lock1(void) __attribute__((context(TEST,0,1)))
-{
-	a();
-}
-
-static void good_lock2(void) __attribute__((context(TEST,0,1)))
-{
-	a();
-	r();
-	a();
-}
-
-static void good_lock3(void) __attribute__((context(TEST,0,1)))
-{
-	a();
-	a();
-	r();
-}
-
-static void good_unlock1(void) __attribute__((context(TEST,1,0)))
-{
-	r();
-}
-
-static void good_unlock2(void) __attribute__((context(TEST,1,0)))
-{
-	a();
-	r();
-	r();
-}
-
-static void warn_lock1(void)
-{
-	a();
-}
-
-static void warn_lock2(void)
-{
-	a();
-	r();
-	a();
-}
-
-static void warn_lock3(void)
-{
-	a();
-	a();
-	r();
-}
-
-static void warn_unlock1(void)
-{
-	r();
-}
-
-static void warn_unlock2(void)
-{
-	a();
-	r();
-	r();
-}
-
-extern int condition, condition2;
-
-static int good_if1(void)
-{
-	a();
-	if(condition) {
-		r();
-		return -1;
-	}
-	r();
-	return 0;
-}
-
-static void good_if2(void)
-{
-	if(condition) {
-		a();
-		r();
-	}
-}
-
-static void good_if3(void)
-{
-	a();
-	if(condition) {
-		a();
-		r();
-	}
-	r();
-}
-
-static int warn_if1(void)
-{
-	a();
-	if(condition)
-		return -1;
-	r();
-	return 0;
-}
-
-static int warn_if2(void)
-{
-	a();
-	if(condition) {
-		r();
-		return -1;
-	}
-	return 0;
-}
-
-static void good_while1(void)
-{
-	a();
-	while(condition)
-		;
-	r();
-}
-
-static void good_while2(void)
-{
-	while(condition) {
-		a();
-		r();
-	}
-}
-
-static void good_while3(void)
-{
-	while(condition) {
-		a();
-		r();
-		if(condition2)
-			break;
-		a();
-		r();
-	}
-}
-
-static void good_while4(void)
-{
-	a();
-	while(1) {
-		if(condition2) {
-			r();
-			break;
-		}
-	}
-}
-
-static void good_while5(void)
-{
-	a();
-	while(1) {
-		r();
-		if(condition2)
-			break;
-		a();
-	}
-}
-
-static void warn_while1(void)
-{
-	while(condition) {
-		a();
-	}
-}
-
-static void warn_while2(void)
-{
-	while(condition) {
-		r();
-	}
-}
-
-static void warn_while3(void)
-{
-	while(condition) {
-		a();
-		if(condition2)
-			break;
-		r();
-	}
-}
-
-static void good_goto1(void)
-{
-    a();
-    goto label;
-label:
-    r();
-}
-
-static void good_goto2(void)
-{
-    a();
-    goto label;
-    a();
-    r();
-label:
-    r();
-}
-
-static void good_goto3(void)
-{
-    a();
-    if(condition)
-        goto label;
-    a();
-    r();
-label:
-    r();
-}
-
-static void good_goto4(void)
-{
-    if(condition)
-        goto label;
-    a();
-    r();
-label:
-    ;
-}
-
-static void good_goto5(void)
-{
-    a();
-    if(condition)
-        goto label;
-    r();
-    return;
-label:
-    r();
-}
-
-static void warn_goto1(void)
-{
-    a();
-    goto label;
-    r();
-label:
-    ;
-}
-
-static void warn_goto2(void)
-{
-    a();
-    goto label;
-    r();
-label:
-    a();
-    r();
-}
-
-static void warn_goto3(void)
-{
-    a();
-    if(condition)
-        goto label;
-    r();
-label:
-    r();
-}
-
-static void warn_multiple1(void)
-{
-    a();
-    a2();
-}
-
-static void warn_multiple2(void)
-{
-    a2();
-    a();
-}
-
-static void warn_mixed1(void)
-{
-    a2();
-    r();
-}
-
-static void warn_mixed2(void)
-{
-    a2();
-    if (condition) {
-        a();
-        r2();
-    }
-    r();
-}
-
-static void warn_mixed3(void)
-{
-    a2();
-    if (condition) {
-        r2();
-        return;
-    }
-    r();
-}
-
-static void warn_mixed4(void)
-{
-    a2();
-    if (condition) {
-        a();
-        r();
-        return;
-    }
-    r();
-}
-
-static void good_mixed1(void)
-{
-    if (condition) {
-        a();
-        r();
-    } else {
-        a2();
-        r2();
-    }
-}
-
-static void good_mixed2(void)
-{
-    if (condition) {
-        a();
-        r();
-    }
-    a2();
-    r2();
-}
-
-static int need_lock(void) __attribute__((context(TEST,1,1)))
-{
-}
-
-static void need_lock_exact(void) __attribute__((exact_context(TEST,1,1)))
-{
-}
-
-static void need_lock2(void) __attribute__((context(TEST,1,1)))
-{
-    need_lock();
-}
-
-static void good_fn(void)
-{
-    a();
-    need_lock();
-    r();
-}
-
-static void good_fn2(void)
-{
-    a();
-    a();
-    need_lock();
-    r();
-    r();
-}
-
-static void good_fn2(void)
-{
-    a();
-    if (condition)
-        need_lock();
-    r();
-}
-
-static void good_fn3(void) __attribute__((context(TEST,1,1)))
-{
-    if (condition)
-        need_lock2();
-}
-
-static void warn_fn(void)
-{
-    a2();
-    need_lock();
-    r2();
-}
-
-static void warn_fn2(void)
-{
-    a2();
-    need_lock2();
-    r2();
-}
-
-static void good_exact_fn(void)
-{
-    a();
-    need_lock_exact();
-    r();
-}
-
-static void warn_exact_fn1(void)
-{
-    a();
-    a();
-    need_lock_exact();
-    r();
-    r();
-}
-
-static void warn_exact_fn2(void)
-{
-    a2();
-    need_lock_exact();
-    r2();
-}
-
-static inline void need_lock3(void) __attribute__((context(TEST,1,1)))
-{
-}
-
-static void warn_fn3(void)
-{
-    a2();
-    need_lock3();
-    r2();
-}
-
-#define __acquire(x)	__context__(x,1)
-#define __release(x)	__context__(x,-1)
-
-#define rl() \
-  do { __acquire(RCU); } while (0)
-
-#define ru() \
-  do { __release(RCU); } while (0)
-
-static void good_mixed_with_if(void)
-{
-    rl();
-
-    if (condition) {
-        a();
-        r();
-    }
-
-    ru();
-}
-
-/*
- * check-name: Check -Wcontext with lock names
- *
- * check-error-start
-context-named.c:86:3: warning: context imbalance in 'warn_lock1': wrong count at exit
-context-named.c:86:3:    context 'TEST': wanted 0, got 1
-context-named.c:93:3: warning: context imbalance in 'warn_lock2': wrong count at exit
-context-named.c:93:3:    context 'TEST': wanted 0, got 1
-context-named.c:100:3: warning: context imbalance in 'warn_lock3': wrong count at exit
-context-named.c:100:3:    context 'TEST': wanted 0, got 1
-context-named.c:105:3: warning: context problem in 'warn_unlock1': 'r' expected different context
-context-named.c:105:3:    context 'TEST': wanted >= 1, got 0
-context-named.c:112:3: warning: context problem in 'warn_unlock2': 'r' expected different context
-context-named.c:112:3:    context 'TEST': wanted >= 1, got 0
-context-named.c:152:9: warning: context imbalance in 'warn_if1': wrong count at exit
-context-named.c:152:9:    context 'TEST': wanted 0, got 1
-context-named.c:162:9: warning: context imbalance in 'warn_if2': wrong count at exit
-context-named.c:162:9:    context 'TEST': wanted 0, got 1
-context-named.c:218:4: warning: context imbalance in 'warn_while1': wrong count at exit
-context-named.c:218:4:    context 'TEST': wanted 0, got 1
-context-named.c:225:4: warning: context problem in 'warn_while2': 'r' expected different context
-context-named.c:225:4:    context 'TEST': wanted >= 1, got 0
-context-named.c:235:4: warning: context imbalance in 'warn_while3': wrong count at exit
-context-named.c:235:4:    context 'TEST': wanted 0, got 1
-context-named.c:295:5: warning: context imbalance in 'warn_goto1': wrong count at exit
-context-named.c:295:5:    context 'TEST': wanted 0, got 1
-context-named.c:305:6: warning: context imbalance in 'warn_goto2': wrong count at exit
-context-named.c:305:6:    context 'TEST': wanted 0, got 1
-context-named.c:315:6: warning: context problem in 'warn_goto3': 'r' expected different context
-context-named.c:315:6:    context 'TEST': wanted >= 1, got 0
-context-named.c:321:7: warning: context imbalance in 'warn_multiple1': wrong count at exit
-context-named.c:321:7:    context 'TEST': wanted 0, got 1
-context-named.c:327:6: warning: context imbalance in 'warn_multiple2': wrong count at exit
-context-named.c:327:6:    context 'TEST2': wanted 0, got 1
-context-named.c:333:6: warning: context problem in 'warn_mixed1': 'r' expected different context
-context-named.c:333:6:    context 'TEST': wanted >= 1, got 0
-context-named.c:343:6: warning: context problem in 'warn_mixed2': 'r' expected different context
-context-named.c:343:6:    context 'TEST': wanted >= 1, got 0
-context-named.c:353:6: warning: context problem in 'warn_mixed3': 'r' expected different context
-context-named.c:353:6:    context 'TEST': wanted >= 1, got 0
-context-named.c:364:6: warning: context imbalance in 'warn_mixed4': wrong count at exit
-context-named.c:364:6:    context 'TEST2': wanted 0, got 1
-context-named.c:434:14: warning: context problem in 'warn_fn': 'need_lock' expected different context
-context-named.c:434:14:    context 'TEST': wanted >= 1, got 0
-context-named.c:441:15: warning: context problem in 'warn_fn2': 'need_lock2' expected different context
-context-named.c:441:15:    context 'TEST': wanted >= 1, got 0
-context-named.c:456:20: warning: context problem in 'warn_exact_fn1': 'need_lock_exact' expected different context
-context-named.c:456:20:    context 'TEST': wanted 1, got 2
-context-named.c:464:20: warning: context problem in 'warn_exact_fn2': 'need_lock_exact' expected different context
-context-named.c:464:20:    context 'TEST': wanted 1, got 0
-context-named.c:475:15: warning: context problem in 'warn_fn3': 'need_lock3' expected different context
-context-named.c:475:15:    context 'TEST': wanted >= 1, got 0
- * check-error-end
- */
diff --git a/validation/context-statement.c b/validation/context-statement.c
deleted file mode 100644
index fd79a6a..0000000
--- a/validation/context-statement.c
+++ /dev/null
@@ -1,69 +0,0 @@
-#define a() __context__(LOCK, 1)
-#define r() __context__(LOCK, -1)
-#define m() __context__(LOCK, 0, 1)
-#define m2() __context__(LOCK, 0, 2)
-
-static void good_ar(void)
-{
-    a();
-    r();
-}
-
-static void bad_arr(void)
-{
-    a();
-    r();
-    r();
-}
-
-static void good_macro1(void)
-{
-    a();
-    m();
-    r();
-}
-
-static void good_macro2(void)
-{
-    a();
-    a();
-    m();
-    m2();
-    r();
-    r();
-}
-
-static void bad_macro1(void)
-{
-    m();
-    a();
-    r();
-}
-
-static void bad_macro2(void)
-{
-    a();
-    r();
-    m();
-}
-
-static void bad_macro3(void)
-{
-    r();
-    a();
-}
-
-/*
- * check-name: Check __context__ statement with required context
- *
- * check-error-start
-context-statement.c:16:8: warning: context imbalance in 'bad_arr': unexpected unlock
-context-statement.c:16:8:    context 'LOCK': wanted 0, got -1
-context-statement.c:38:5: warning: context imbalance in 'bad_macro1': __context__ statement expected different context
-context-statement.c:38:5:    context 'LOCK': wanted >= 1, got 0
-context-statement.c:47:5: warning: context imbalance in 'bad_macro2': __context__ statement expected different context
-context-statement.c:47:5:    context 'LOCK': wanted >= 1, got 0
-context-statement.c:53:5: warning: context imbalance in 'bad_macro3': __context__ statement expected different context
-context-statement.c:53:5:    context 'LOCK': wanted >= 0, got -1
- * check-error-end
- */
diff --git a/validation/context.c b/validation/context.c
index 0b45ba3..4b15e75 100644
--- a/validation/context.c
+++ b/validation/context.c
@@ -314,109 +314,23 @@ static void warn_cond_lock1(void)
         condition2 = 1; /* do stuff */
     r();
 }
-
-static void warn_odd_looping(void)
-{
-    int i;
-
-    for (i = 0; i < 2; i++)
-        a();
-    for (i = 0; i < 2; i++)
-        r();
-}
-
-static void warn_huge_switch(void)
-{
-    a();
-
-    switch(condition) {
-    case 1:
-        r();
-        break;
-    case 2:
-        r();
-        break;
-    case 3:
-        r();
-        break;
-    case 4:
-        r();
-        break;
-    case 5:
-        r();
-        break;
-    case 11:
-        r();
-        break;
-    case 12:
-        r();
-        break;
-    case 13:
-        r();
-        break;
-    case 14:
-        r();
-    case 15:
-        r();
-        break;
-    case 16:
-        r();
-        break;
-    case 17:
-        r();
-        break;
-    }
-}
-
-static int warn_conditional(void)
-{
-    if (condition)
-        return 0;
-
-    a();
-    if (condition == 0)
-        return 1;
-    r();
-    return 0;
-}
-
 /*
  * check-name: Check -Wcontext
  *
  * check-error-start
-context.c:71:3: warning: context imbalance in 'warn_lock1': wrong count at exit
-context.c:71:3:    default context: wanted 0, got 1
-context.c:78:3: warning: context imbalance in 'warn_lock2': wrong count at exit
-context.c:78:3:    default context: wanted 0, got 1
-context.c:85:3: warning: context imbalance in 'warn_lock3': wrong count at exit
-context.c:85:3:    default context: wanted 0, got 1
-context.c:90:3: warning: context problem in 'warn_unlock1': 'r' expected different context
-context.c:90:3:    default context: wanted >= 1, got 0
-context.c:97:3: warning: context problem in 'warn_unlock2': 'r' expected different context
-context.c:97:3:    default context: wanted >= 1, got 0
-context.c:137:9: warning: context imbalance in 'warn_if1': wrong count at exit
-context.c:137:9:    default context: wanted 0, got 1
-context.c:147:9: warning: context imbalance in 'warn_if2': wrong count at exit
-context.c:147:9:    default context: wanted 0, got 1
-context.c:203:4: warning: context imbalance in 'warn_while1': wrong count at exit
-context.c:203:4:    default context: wanted 0, got 1
-context.c:210:4: warning: context problem in 'warn_while2': 'r' expected different context
-context.c:210:4:    default context: wanted >= 1, got 0
-context.c:220:4: warning: context imbalance in 'warn_while3': wrong count at exit
-context.c:220:4:    default context: wanted 0, got 1
-context.c:280:5: warning: context imbalance in 'warn_goto1': wrong count at exit
-context.c:280:5:    default context: wanted 0, got 1
-context.c:290:6: warning: context imbalance in 'warn_goto2': wrong count at exit
-context.c:290:6:    default context: wanted 0, got 1
-context.c:300:6: warning: context problem in 'warn_goto3': 'r' expected different context
-context.c:300:6:    default context: wanted >= 1, got 0
-context.c:315:6: warning: context problem in 'warn_cond_lock1': 'r' expected different context
-context.c:315:6:    default context: wanted >= 1, got 0
-context.c:325:10: warning: context problem in 'warn_odd_looping': 'r' expected different context
-context.c:325:10:    default context: wanted >= 1, got 0
-context.c:360:10: warning: context problem in 'warn_huge_switch': 'r' expected different context
-context.c:360:10:    default context: wanted >= 1, got 0
-context.c:380:12: warning: context imbalance in 'warn_conditional': wrong count at exit
-context.c:380:12:    default context: wanted 0, got 1
+context.c:69:13: warning: context imbalance in 'warn_lock1' - wrong count at exit
+context.c:74:13: warning: context imbalance in 'warn_lock2' - wrong count at exit
+context.c:81:13: warning: context imbalance in 'warn_lock3' - wrong count at exit
+context.c:88:13: warning: context imbalance in 'warn_unlock1' - unexpected unlock
+context.c:93:13: warning: context imbalance in 'warn_unlock2' - unexpected unlock
+context.c:131:12: warning: context imbalance in 'warn_if1' - wrong count at exit
+context.c:140:12: warning: context imbalance in 'warn_if2' - different lock contexts for basic block
+context.c:202:2: warning: context imbalance in 'warn_while1' - different lock contexts for basic block
+context.c:210:3: warning: context imbalance in 'warn_while2' - unexpected unlock
+context.c:216:2: warning: context imbalance in 'warn_while3' - wrong count at exit
+context.c:274:13: warning: context imbalance in 'warn_goto1' - wrong count at exit
+context.c:283:13: warning: context imbalance in 'warn_goto2' - wrong count at exit
+context.c:300:5: warning: context imbalance in 'warn_goto3' - different lock contexts for basic block
+context.c:315:5: warning: context imbalance in 'warn_cond_lock1' - different lock contexts for basic block
  * check-error-end
  */
-- 
1.6.0.6



--
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