X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fforeach%2Fforeach.c;h=de79eb59af782e8544520e19b6750212a132ac97;hp=70040ee986a5116bb407ea5ebc3ab703d51abd98;hb=34eab93cc6fbd18967810ae984b52615c995b199;hpb=d1d29462c77d909b8e7a6b960bcc71c9422e0f8f;ds=sidebyside diff --git a/ccan/foreach/foreach.c b/ccan/foreach/foreach.c index 70040ee9..de79eb59 100644 --- a/ccan/foreach/foreach.c +++ b/ccan/foreach/foreach.c @@ -12,19 +12,28 @@ struct iter_info { struct list_node list; const void *index; unsigned int i, num; + bool onstack; }; +/* Is pointer still downstack from some other onstack var? */ +static bool on_stack(const void *ptr, const void *onstack) +{ +#if HAVE_STACK_GROWS_UPWARDS + return ptr < onstack; +#else + return ptr > onstack; +#endif +} + static void free_old_iters(const void *index) { struct iter_info *i, *next; list_for_each_safe(&iters, i, next, list) { /* If we're re-using an index, free the old one. - * Otherwise, if it's past i on the stack, it's old. Don't - * assume stack direction, but we know index is downstack. */ + * Otherwise, discard if it's passed off stack. */ if (i->index == index - || (((uintptr_t)index < (uintptr_t)&i) - == ((uintptr_t)&i < (uintptr_t)i->index))) { + || (i->onstack && !on_stack(i->index, &i))) { list_del(&i->list); free(i); } @@ -47,6 +56,7 @@ static struct iter_info *new_iter(const void *index) struct iter_info *info = malloc(sizeof *info); info->index = index; info->i = info->num = 0; + info->onstack = on_stack(index, &info); list_add(&iters, &info->list); return info; };