llvm-project/clang/test/Analysis/new-ctor-conservative.cpp
Kristóf Umann a504ddc8bf [analyzer] Initialize regions returned by CXXNew to undefined
Discourse mail:
https://discourse.llvm.org/t/analyzer-why-do-we-suck-at-modeling-c-dynamic-memory/65667

malloc() returns a piece of uninitialized dynamic memory. We were (almost)
always able to model this behaviour. Its C++ counterpart, operator new is a
lot more complex, because it allows for initialization, the most complicated of which is the usage of constructors.

We gradually became better in modeling constructors, but for some reason, most
likely for reasons lost in history, we never actually modeled the case when the
memory returned by operator new was just simply uninitialized. This patch
(attempts) to fix this tiny little error.

Differential Revision: https://reviews.llvm.org/D135375
2022-10-26 17:22:12 +02:00

56 lines
1.4 KiB
C++

// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-allocator-inlining=true -std=c++11 -verify -analyzer-config eagerly-assume=false %s
void clang_analyzer_eval(bool);
void clang_analyzer_warnIfReached();
struct S {
int x;
S() : x(1) {}
~S() {}
};
void checkConstructorInlining() {
S *s = new S;
clang_analyzer_eval(s->x == 1); // expected-warning{{TRUE}}
}
void checkNewPODunit() {
int *i = new int;
clang_analyzer_eval(*i == 0); // expected-warning{{The left operand of '==' is a garbage value [core.UndefinedBinaryOperatorResult]}}
}
void checkNewPOD() {
int *j = new int();
clang_analyzer_eval(*j == 0); // expected-warning{{TRUE}}
int *k = new int(5);
clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}}
}
void checkNewArray() {
S *s = new S[10];
// FIXME: Handle big array construction
clang_analyzer_eval(s[0].x == 1); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(s[1].x == 1); // expected-warning{{UNKNOWN}}
s = new S[4];
clang_analyzer_eval(s[0].x == 1); // expected-warning{{TRUE}}
clang_analyzer_eval(s[1].x == 1); // expected-warning{{TRUE}}
}
struct NullS {
NullS() {
if (this) {}
}
NullS(int x) {
if (!this) {
clang_analyzer_warnIfReached(); // no-warning
}
}
};
void checkNullThis() {
NullS *nulls = new NullS(); // no-crash
NullS *nulls2 = new NullS(0);
}