Skip to content

Commit 48842c8

Browse files
Merge pull request #1593 from geoffw0/stackforreturn
CPP: Fix FP in AllocaInLoop.ql
2 parents 59a402f + 0a49a68 commit 48842c8

File tree

4 files changed

+44
-3
lines changed

4 files changed

+44
-3
lines changed

change-notes/1.22/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
| **Query** | **Expected impact** | **Change** |
1313
|----------------------------|------------------------|------------------------------------------------------------------|
14+
| Call to alloca in a loop (`cpp/alloca-in-loop`) | Fewer false positive results | Fixed false positives where the stack allocation could not be reached multiple times in the loop, typically due to a `break` or `return` statement. |
1415
| Continue statement that does not continue (`cpp/continue-in-false-loop`) | Fewer false positive results | Analysis is now restricted to `do`-`while` loops. This query is now run and displayed by default on LGTM. |
1516
| Expression has no effect (`cpp/useless-expression`) | Fewer false positive results | Calls to functions with the `weak` attribute are no longer considered to be side effect free, because they could be overridden with a different implementation at link time. |
1617
| No space for zero terminator (`cpp/no-space-for-terminator`) | Fewer false positive results | False positives involving strings that are not null-terminated have been excluded. |

cpp/ql/src/Likely Bugs/Memory Management/AllocaInLoop.ql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,11 @@ class LoopWithAlloca extends Stmt {
322322
}
323323
}
324324

325-
from LoopWithAlloca l
325+
from LoopWithAlloca l, AllocaCall alloc
326326
where
327327
not l.(DoStmt).getCondition().getValue() = "0" and
328-
not l.isTightlyBounded()
329-
select l.getAnAllocaCall(), "Stack allocation is inside a $@ loop.", l,
328+
not l.isTightlyBounded() and
329+
alloc = l.getAnAllocaCall() and
330+
alloc.getASuccessor*() = l.(Loop).getStmt()
331+
select alloc, "Stack allocation is inside a $@ loop.", l,
330332
l.toString()

cpp/ql/test/query-tests/Likely Bugs/Memory Management/AllocaInLoop/AllocaInLoop.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
| AllocaInLoop1.cpp:31:18:31:23 | call to __builtin_alloca | Stack allocation is inside a $@ loop. | AllocaInLoop1.cpp:22:2:39:2 | for(...;...;...) ... | for(...;...;...) ... |
22
| AllocaInLoop1.cpp:55:19:55:24 | call to __builtin_alloca | Stack allocation is inside a $@ loop. | AllocaInLoop1.cpp:45:2:64:2 | for(...;...;...) ... | for(...;...;...) ... |
33
| AllocaInLoop1.cpp:80:19:80:24 | call to __builtin_alloca | Stack allocation is inside a $@ loop. | AllocaInLoop1.cpp:71:3:88:3 | for(...;...;...) ... | for(...;...;...) ... |
4+
| AllocaInLoop1.cpp:110:19:110:24 | call to __builtin_alloca | Stack allocation is inside a $@ loop. | AllocaInLoop1.cpp:109:2:113:13 | do (...) ... | do (...) ... |
45
| AllocaInLoop1ms.cpp:28:18:28:24 | call to _alloca | Stack allocation is inside a $@ loop. | AllocaInLoop1ms.cpp:19:2:36:2 | for(...;...;...) ... | for(...;...;...) ... |
56
| AllocaInLoop1ms.cpp:52:19:52:26 | call to _malloca | Stack allocation is inside a $@ loop. | AllocaInLoop1ms.cpp:42:2:63:2 | for(...;...;...) ... | for(...;...;...) ... |
67
| AllocaInLoop1ms.cpp:79:19:79:25 | call to _alloca | Stack allocation is inside a $@ loop. | AllocaInLoop1ms.cpp:70:3:87:3 | for(...;...;...) ... | for(...;...;...) ... |

cpp/ql/test/query-tests/Likely Bugs/Memory Management/AllocaInLoop/AllocaInLoop1.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,40 @@ void baz(const struct vtype* vec, int count) {
8888
}
8989
} while (0);
9090
}
91+
92+
// case 4: alloca contained in an unbounded loop, followed by break.
93+
void case4() {
94+
char *buffer;
95+
96+
do {
97+
buffer = (char*)alloca(1024); // GOOD
98+
99+
break;
100+
} while (1);
101+
102+
delete [] buffer;
103+
}
104+
105+
// case 5: alloca contained in an unbounded loop, followed by continue.
106+
void case5() {
107+
char *buffer;
108+
109+
do {
110+
buffer = (char*)alloca(1024); // BAD
111+
112+
continue;
113+
} while (1);
114+
115+
delete [] buffer;
116+
}
117+
118+
// case 6: alloca contained in an unbounded loop, followed by return.
119+
char *case6() {
120+
char *buffer;
121+
122+
do {
123+
buffer = (char*)alloca(1024); // GOOD
124+
125+
return buffer;
126+
} while (1);
127+
}

0 commit comments

Comments
 (0)