Skip to content

incorrect modeling of std::optional in cplusplus.NewDelete leads to incorrect warnings #119415

@vtjnash

Description

@vtjnash

The clang-analyzer incorrectly models the default ~ function for a union object (it calls ~ on some of the options, in contradiction to the C++ standard and actual implementation which does not call ~ on any fields). This results in declaration of double-frees (or lost memory) which don't actually occur at runtime for sample code like this.
cat dtor-test.cpp

#include <iostream>
#include <optional>

class C {
  int *once;
public:
  C(int) {
    std::cout << "C Ctor" << std::endl;
    once = new int[3];
  }
  C(C&&) = delete;
  ~C() {
    std::cout << "C Dtor" << std::endl;
    delete[] once;
  }
};

int main() {
  std::optional<C> S{1};
  return 0;
}
$ clang++ -fPIE -std=c++20 dtor-test.cpp  && ./a.out # demo that clang++ runs correctly
C Ctor
C Dtor
$ g++ -fPIE -std=c++20 dtor-test.cpp  && ./a.out # demo that g++ runs correctly
C Ctor
C Dtor
$ clang++ --analyze -analyzer-output=text -std=c++20 dtor-test.cpp # demo that clang-analyzer is wrong
dtor-test.cpp:14:5: warning: Attempt to free released memory [cplusplus.NewDelete]
   14 |     delete[] once;
      |     ^

from JuliaLang/julia#56130 (comment)

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions