Dear suckless folks,

sorry, for being ignorant, but I have one question regarding the warning below from Clang’s static analyzer scan-build.

```
dwm.c:480:4: warning: Use of memory after it is freed
                        unmanage(m->stack, 0);
                        ^~~~~~~~~~~~~~~~~~~~~
```

The code [1], looks like below.

```
[…]
void
detach(Client *c)
{
        Client **tc;

        for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
        *tc = c->next;
}

void
detachstack(Client *c)
{
        Client **tc, *t;

        for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
        *tc = c->snext;

        if (c == c->mon->sel) {
                for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext);
                c->mon->sel = t;
        }
}
[…]
void
unmanage(Client *c, int destroyed)
{
        Monitor *m = c->mon;
        XWindowChanges wc;

        /* The server grab construct avoids race conditions. */
        detach(c);
        detachstack(c);
        if (!destroyed) {
                wc.border_width = c->oldbw;
                XGrabServer(dpy);
                XSetErrorHandler(xerrordummy);
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
                XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
                setclientstate(c, WithdrawnState);
                XSync(dpy, False);
                XSetErrorHandler(xerror);
                XUngrabServer(dpy);
        }
        free(c);
        focus(NULL);
        updateclientlist();
        arrange(m);
}
[…]
void
cleanup(void)
{
        Arg a = {.ui = ~0};
        Layout foo = { "", NULL };
        Monitor *m;
        size_t i;

        view(&a);
        selmon->lt[selmon->sellt] = &foo;
        for (m = mons; m; m = m->next)
                if (m->stack)
                        unmanage(m->stack, 0);
        XUngrabKey(dpy, AnyKey, AnyModifier, root);
        while (mons)
                cleanupmon(mons);
        for (i = 0; i < CurLast; i++)
                drw_cur_free(drw, cursor[i]);
        for (i = 0; i < SchemeLast; i++)
                free(scheme[i]);
        drw_free(drw);
        XSync(dpy, False);
        XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
        XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
}
[…]
```

Unfortunately, my C knowledge is not good enough to understand, why the while loop is used here. Even reading the called functions, I don’t see why `m->stack`, a pointer, should be checked in the while condition. Is it set to `NULL` somewhere?


Thank you in advance.


Best regards,

Paul


[1] http://git.suckless.org/dwm/tree/dwm.c#n480

Reply via email to