Repository: neovim/neovim
File: src/nvim/buffer.c (C)

Code before:
        break;
      }
    }

    // If the buffer to be deleted is not the current one, delete it here.
    if (buf != curbuf) {
      if (jop_flags & kOptJopFlagClean) {
        // Remove the buffer to be deleted from the jump list.
        mark_jumplist_forget_file(curwin, buf_fnum);
      }

      close_windows(buf, false);

      if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) {
        close_buffer(NULL, buf, action, false, false);
      }
      return OK;
    }

    // Deleting the current buffer: Need to find another buffer to go to.
    // There should be another, otherwise it would have been handled
    // above.  However, autocommands may have deleted all buffers.
    // First use au_new_curbuf.br_buf, if it is valid.
    // Then prefer the buffer we most recently visited.
    // Else try to find one that is loaded, after the current buffer,
    // then before the current buffer.
    // Finally use any buffer.
    buf = NULL;  // Selected buffer.
    bp = NULL;   // Used when no loaded buffer found.
    if (au_new_curbuf.br_buf != NULL && bufref_valid(&au_new_curbuf)) {
      buf = au_new_curbuf.br_buf;
    } else if (curwin->w_jumplistlen > 0) {
      if (jop_flags & kOptJopFlagClean) {
        // Remove the buffer from the jump list.
        mark_jumplist_forget_file(curwin, buf_fnum);
      }

      // It's possible that we removed all jump list entries, in that case we need to try another
      // approach
      if (curwin->w_jumplistlen > 0) {
        int jumpidx = curwin->w_jumplistidx;

        if (jop_flags & kOptJopFlagClean) {
          // If the index is the same as the length, the current position was not yet added to the
          // jump list. So we can safely go back to the last entry and search from there.
          if (jumpidx == curwin->w_jumplistlen) {
            jumpidx = curwin->w_jumplistidx = curwin->w_jumplistlen - 1;
          }
        } else {
          jumpidx--;
          if (jumpidx < 0) {

Review comment (suggestion):
coverity noticed something. probably a false positive since `curwin` must always be valid. do we have a way to assert that `curwin` is valid?

```
CID 642686:         Memory - illegal accesses  (USE_AFTER_FREE)
/src/nvim/buffer.c: 1480             in do_buffer_ext()
1474         // Finally use any buffer.  Skip buffers that are closing throughout.
1475         buf = NULL;  // Selected buffer.
1476         bp = NULL;   // Used when no loaded buffer found.
1477         if (au_new_curbuf.br_buf != NULL && bufref_valid(&au_new_curbuf)
1478             && !au_new_curbuf.br_buf->b_locked_split) {
1479           buf = au_new_curbuf.br_buf;
>>>     CID 642686:         Memory - illegal accesses  (USE_AFTER_FREE)
>>>     Dereferencing freed pointer "curwin".
1480         } else if (curwin->w_jumplistlen > 0) {
1481           if (jop_flags & kOptJopFlagClean) {
1482             // Remove the buffer from the jump list.
1483             mark_jumplist_forget_file(curwin, buf_fnum);
1484           }
```

Code after:
        // Remove the buffer to be deleted from the jump list.
        mark_jumplist_forget_file(curwin, buf_fnum);
      }

      close_windows(buf, false);

      if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) {
        close_buffer(NULL, buf, action, false, false);
      }
      return OK;
    }

    // Deleting the current buffer: Need to find another buffer to go to.
    // There should be another, otherwise it would have been handled
    // above.  However, autocommands may have deleted all buffers.
    // First use au_new_curbuf.br_buf, if it is valid.
    // Then prefer the buffer we most recently visited.
    // Else try to find one that is loaded, after the current buffer,
    // then before the current buffer.
    // Finally use any buffer.  Skip buffers that are closing throughout.
    buf = NULL;  // Selected buffer.
    bp = NULL;   // Used when no loaded buffer found.
    if (au_new_curbuf.br_buf != NULL && bufref_valid(&au_new_curbuf)
        && !au_new_curbuf.br_buf->b_locked_split) {
      buf = au_new_curbuf.br_buf;
    } else if (curwin->w_jumplistlen > 0) {
      if (jop_flags & kOptJopFlagClean) {
        // Remove the buffer from the jump list.
        mark_jumplist_forget_file(curwin, buf_fnum);
      }

      // It's possible that we removed all jump list entries, in that case we need to try another
      // approach
      if (curwin->w_jumplistlen > 0) {
        int jumpidx = curwin->w_jumplistidx;

        if (jop_flags & kOptJopFlagClean) {
          // If the index is the same as the length, the current position was not yet added to the
          // jump list. So we can safely go back to the last entry and search from there.
          if (jumpidx == curwin->w_jumplistlen) {
            jumpidx = curwin->w_jumplistidx = curwin->w_jumplistlen - 1;
          }
        } else {
          jumpidx--;
          if (jumpidx < 0) {
            jumpidx = curwin->w_jumplistlen - 1;
          }
        }

        forward = jumpidx;
        while ((jop_flags & kOptJopFlagClean) || jumpidx != curwin->w_jumplistidx) {