Skip to content

[analyzer] FP for cplusplus.PlacementNew #149240

@puetzk

Description

@puetzk
#include <new>

int main() {
    void *buf = ::operator new(sizeof(int)*2);
    int * placement_int = new (buf) int[2];
    placement_int[0] = 42;
    ::operator delete(buf);
}

clang-tidy produces

<source>:5:27: warning: Storage provided to placement new is only 8 bytes, whereas the allocated array type requires more space for internal needs [clang-analyzer-cplusplus.PlacementNew]
    5 |     int * placement_int = new (buf) int[2];
      |                           ^~~~~~~~~~~~~~~~
<source>:4:5: note: 'buf' initialized here
    4 |     void *buf = ::operator new(sizeof(int)*2);
      |     ^~~~~~~~~
<source>:5:27: note: Storage provided to placement new is only 8 bytes, whereas the allocated array type requires more space for internal needs
    5 |     int * placement_int = new (buf) int[2];
      |                           ^~~~~~~~~~~~~~~~

Reproduced in https://godbolt.org/z/MYGc5qfn6 using clang version 22.0.0git (https://github.com/llvm/llvm-project.git 82d7405)

I think this warning is incorrect, as described at https://stackoverflow.com/questions/8720425/array-placement-new-requires-unspecified-overhead-in-the-buffer and in https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2382 or https://cplusplus.github.io/CWG/issues/2382.html. This is a non-allocating placement new, in which case (per that defect resolution) no additional space may be requested.

So I think these "array overhead" warnings are always false-positives. However, they do seem to have been added in May 2020:
https://github.com/llvm/llvm-project/blame/1c541aa9f9a2453324724bfb9d661bc672778d10/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp#L120-L134 shows it came in with 7c37684 and https://reviews.llvm.org/D76996
That dates this first being added to clang after that DR had been reported, voted on, and the resolution accepted into CD5. So I don't think they are simply outdated; maybe the author/reviewers were unaware of the defect report?

Or maybe I'm misunderstanding something and this really is buggy code - "I'm wrong" is certainly possible too :-)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions