<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/58369>58369</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Clang static analyzer could try catching invariant loop conditions
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          ryao
      </td>
    </tr>
</table>

<pre>
    Recently, I wrote this C code in a patch that refactored a mature codebase to avoid a very rare bug:

`for (zv = avl_first(t); zv != NULL; AVL_NEXT(t, zv)) { stuff(); }`

Unfortunately, it should have been, so the result had been an infinite loop:

`for (zv = avl_first(t); zv != NULL; zv = AVL_NEXT(t, zv)) { stuff(); }`

The loop block has been simplified since it is not important here.

I ran Clang 14's static analyzer on this to try to get a hint as to what I did wrong, but it missed this. I missed it despite looking at the patch many times. Another developer looked at the patch multiple times and missed this too.

While this mistake is more common for new C programmers, it is incredibly rare for experienced C programmers, which causes us to miss it when we make it. I ended up using a mix of dynamic tracing and print statements (because the dynamic tracing was a little quirky) before finally identifying the problem. This was in kernel code. It caused a memory leak that took down the system in less than 2 minutes and the system would take several minutes to reboot, so I had very little time try to diagnose what I did wrong at runtime until I finally identified the problem loop and put a `msleep(100);` call into it. :/

A loop invariant condition like this seems like something that would be fairly easy to check. It would be nice if Clang's static analyzer could warn about this (while not warning about the obviously intentional `while(1) { doSomething(); }`.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJytVcuS2zYQ_BrqgopKpJ488LCPbNVWbfmQrBPfXCA5FBGBAAOAouWvTw9IreW1b85Booh5oKd7ZlTa-lL8QRWZoC9J9iCexehsIBFa5cWDqGxNQhkhRS9D1eJYBuGokVWwjmqcdzIMjqJjKT0CrZBnq9h0JncRTsJaDsdkfZesHpPV9Xu3aqwTSXb4ehbJ-hFB-nOjnA84widP1veCTVnK1g8fX1745O6vl88ffv_0Ojk9wINds1wk-3vhw9A0sMzRyf4Rt9xe-tHgzjAYGWiqVgXhWzvoWrTyDJhEho-9RaGEOv2gA0x1tAhpQEWjjAI_2tr-_ylpdv61yl7bCZIota1OgOwnyF51vVaNglRemYq4YghrLB5dDzKkQYHkaHmb7RmqGfGgpTmKdJNkew8EMqgKFEh9-UpOWDO1COQOUBmPIwVo3ioklPF85F55FjV6AT1ljlxVOQSG0CnvAYkzLOEyv8JQk-9nek8KtyMDKzE1XycNblIdIegOJQA3As6kbY9fHMId-V0E9FO9pikK6OvbqwHSflf3363Sc-vDLcgTMVmdjf3ddaiZBTY0YjJ6Z49Odh05P3cSXEExpkKVeu57dqcvQKcI5Nc_ho2tAsxKDh7whkgbA-R0Ywv9RkLVDCMwT2RqJBl6eEZy4PtF2EbUFyM7qBOcrKIBdfaOlWDZqMN0e-7LkuJNkaD3MSNEk0KrEEDBv4Nypwt3X0kNl4-ulxpVqRq5VHPhiEizs6WmbilemTTOgWVxImdIx5UA1GEqL-4KApcXoUmepk0CAU6itqOJyfzFAyxn0AQO4GFEhhrNEGbxbrzGOLZRI48ecFK_eYJER6W1YZ7l5zjCcRvN9XE7XPu2VvJoLFh536_cSm4w0ZcfGsZ3PCiqb2mYRjCyP_AwYEg7r4l6cJ-uVtP04hCMaI06cTsLy3ske7ptxLspkzJn6RSPaGVNrYJCB2p1mlvUE3V-eve2I5xFUYB64qaEbFI5oCXpY6lVS9UpSvLmYRQvhWYa9p9OehVdR-mwAEs7hOlyVDTGaeFVwsbYd7OdhC3Pyg6emTKBqbJIx3zEIKbjutpq--cV_PsFN8_mgop0t9vuD1m2yxd1sa7zdS4XQUHJYlpSP8fMAle8BxjbNy4jtW-E-sXgdNGG0PtZh-zpqEI7lEvMPF60Pl8fv0Hnf6hCXz1hSAfCCD9tD2ugaotUUrpdZ7msN6tqvysP-xyWXZnLTZ7vst1Cy5K0L5LtfZJlvENiCvxOto8LVWSrLEtX6SZL0_0mX6bVNt3Xm0O2zbeHJpXJZkWdVHrJOJbWHReuiJDw1-ph1NhX_ptReq-Ohiheh_xyCK11hbtIu4j3FhH3f8Y4rRE">