C++: Detect non-allocating placement new

This adds a `NewOrNewArrayExpr.getPlacementPointer` predicate and uses
it in `Alloc.qll` to detect when a `new`-expression is not an
allocation.

User-defined replacements for `operator new` may not be allocations
either, but the code continues to assume that they are. It's possible
that we want to change this assumption in the future or leave it up to
individual queries to decide on which side to err. It's hard to
statically tell whether `operator new` has been overloaded in a
particular file because it can be overloaded by a definition that is not
in scope but is only linked together with that file.
This commit is contained in:
Jonas Jensen
2018-11-22 11:31:19 +01:00
parent a17debac3e
commit 75873bb4a6
8 changed files with 58 additions and 6 deletions

View File

@@ -8,7 +8,5 @@
| test.cpp:42:18:42:23 | call to malloc | This memory is never freed |
| test.cpp:73:18:73:23 | call to malloc | This memory is never freed |
| test.cpp:89:18:89:23 | call to malloc | This memory is never freed |
| test.cpp:150:3:150:21 | new | This memory is never freed |
| test.cpp:153:3:153:17 | new[] | This memory is never freed |
| test.cpp:156:3:156:26 | new | This memory is never freed |
| test.cpp:157:3:157:26 | new[] | This memory is never freed |

View File

@@ -147,10 +147,10 @@ void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
int overloadedNew() {
char buf[sizeof(int)];
new(&buf[0]) int(5); // GOOD [FALSE POSITIVE]
new(&buf[0]) int(5); // GOOD
int five = *(int*)buf;
new(buf) int[1]; // GOOD [FALSE POSITIVE]
new(buf) int[1]; // GOOD
*(int*)buf = 4;
new(std::nothrow) int(3); // BAD