Browse Source

aga: Fix initialization bug in aga_for_each_edge_info

The aga_for_each_edge_info macro is constructed so that if the edge_info
callback returns an error, the for loop terminates early and leaves the
_err parameter set to the error.  On successful completion of the loop,
_err should be zero.

However, on a node with no edges, _err will not be initialized, meaning
that it could be non-zero even on successful (trivial) completion of the
loop.  This fixes the bug.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
David Gibson 10 years ago
parent
commit
2ab26c629f
2 changed files with 5 additions and 3 deletions
  1. 1 1
      ccan/aga/aga.h
  2. 4 2
      ccan/aga/test/api-adjacency.c

+ 1 - 1
ccan/aga/aga.h

@@ -239,7 +239,7 @@ int aga_edge_info(const struct aga_graph *g, const struct aga_node *n,
 	     (_e) = aga_next_edge((_g), (_n), (_e)))
 
 #define aga_for_each_edge_info(_e, _ei, _err, _g, _n)			\
-	for ((_e) = aga_first_edge((_g), (_n));				\
+	for ((_err) = 0, (_e) = aga_first_edge((_g), (_n));		\
 	     (_e) && ((((_err) = aga_edge_info((_g), (_n), (_e), &(_ei)))) == 0); \
 	     (_e) = aga_next_edge((_g), (_n), (_e)))			\
 		if ((_ei).to)

+ 4 - 2
ccan/aga/test/api-adjacency.c

@@ -20,7 +20,7 @@ static void test_adjacency(const char *name,
 		struct aga_edge_info ei;
 		int j = 0;
 		const struct aga_node *from;
-		int err;
+		int err = 0xdeadbeef;
 
 		assert(i < MAX_NODES);
 
@@ -42,6 +42,8 @@ static void test_adjacency(const char *name,
 			ok(err == at[i].to[j], "%s: %p #%d -> ERROR %d",
 			   name, e, at[i].from, at[i].to[j]);
 			continue; /* Move onto next node on errors */
+		} else {
+			ok1(err == 0);
 		}
 		assert(j < MAX_EDGES);
 		ok(at[i].to[j] == 0,
@@ -60,7 +62,7 @@ int main(void)
 	struct error_graph eg;
 	struct traversal1_graph t1g;
 
-	plan_tests(1 + 5 + 30 + 22 + 21 + 33 + 6 + 21);
+	plan_tests(2 + 7 + 35 + 30 + 30 + 42 + 9 + 30);
 
 	trivial_graph_init(&tg);
 	test_adjacency("trivial", &tg.sg, trivial_adjacency);