Strange code in lfs_ctz_traverse triggering clang-analyzer-security.ArrayBound
Author: elupusCreated Jun 22, 2026Updated Jun 22, 2026
I was investigating the warning below (which looks to be a false positive) in lfs_ctz_traverse. I saw something confusing:
int count = 2 - (index & 1);
...
for (int i = 0; i < count-1; i++) {
...
}As far as my human compiler thinks, count can only ever take the value of 2 or 1. And the for loop will only ever run if count is larger or equal to 2. Which in practice means, this is identical to: if (count == 2) so the loop is mostly confusing?
It seems clang-tidy get confused by this too. I don't fully grasp what the intent here is.
/littlefs/lfs.c:3058:16: warning: Out of bound access to memory after the end of 'heads' [clang-analyzer-security.ArrayBound]
3058 | head = heads[count-1];
| ^~~~~~~~~~~~~~
/littlefs/lfs.c:3024:9: note: Assuming 'size' is not equal to 0
3024 | if (size == 0) {
| ^~~~~~~~~
/littlefs/lfs.c:3024:5: note: Taking false branch
3024 | if (size == 0) {
| ^
/littlefs/lfs.c:3030:5: note: Loop condition is true. Entering loop body
3030 | while (true) {
| ^
/littlefs/lfs.c:3032:13: note: Assuming 'err' is 0
3032 | if (err) {
| ^~~
/littlefs/lfs.c:3032:9: note: Taking false branch
3032 | if (err) {
| ^
/littlefs/lfs.c:3036:13: note: Assuming 'index' is not equal to 0
3036 | if (index == 0) {
| ^~~~~~~~~~
/littlefs/lfs.c:3036:9: note: Taking false branch
3036 | if (index == 0) {
| ^
/littlefs/lfs.c:3047:13: note: Assuming 'err' is 0
3047 | if (err) {
| ^~~
/littlefs/lfs.c:3047:9: note: Taking false branch
3047 | if (err) {
| ^
/littlefs/lfs.c:3051:25: note: Assuming the condition is true
3051 | for (int i = 0; i < count-1; i++) {
| ^~~~~~~~~~~
/littlefs/lfs.c:3051:9: note: Loop condition is true. Entering loop body
3051 | for (int i = 0; i < count-1; i++) {
| ^
/littlefs/lfs.c:3053:17: note: Assuming 'err' is 0
3053 | if (err) {
| ^~~
/littlefs/lfs.c:3053:13: note: Taking false branch
3053 | if (err) {
| ^
/littlefs/lfs.c:3051:25: note: Assuming the condition is true
3051 | for (int i = 0; i < count-1; i++) {
| ^~~~~~~~~~~
/littlefs/lfs.c:3051:9: note: Loop condition is true. Entering loop body
3051 | for (int i = 0; i < count-1; i++) {
| ^
/littlefs/lfs.c:3053:17: note: Assuming 'err' is 0
3053 | if (err) {
| ^~~
/littlefs/lfs.c:3053:13: note: Taking false branch
3053 | if (err) {
| ^
/littlefs/lfs.c:3051:25: note: Assuming the condition is false
3051 | for (int i = 0; i < count-1; i++) {
| ^~~~~~~~~~~
/littlefs/lfs.c:3051:9: note: Loop condition is false. Execution continues on line 3058
3051 | for (int i = 0; i < count-1; i++) {
| ^
/littlefs/lfs.c:3058:16: note: Access of 'heads' at index 2, while it holds only 2 'unsigned int' elements
3058 | head = heads[count-1];
| ^~~~~~~~~~~~~~Source: littlefs-project/littlefs