mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 15:16:35 +00:00

A clang user pointed out that messages for the static analyzer undefined assignment checker use the term ‘garbage’, which might have a negative connotation to some users. This change updates the messages to use the term ‘uninitialized’. This is the usual reason why a value is undefined in the static analyzer and describes the logical error that a programmer should take action to fix. Out-of-bounds reads can also produce undefined values in the static analyzer. The right long-term design is to have to the array bounds checker cover out-of-bounds reads, so we do not cover that case in the updated messages. The recent improvements to the array bounds checker make it a candidate to add to the core set of checkers. rdar://133418644
389 lines
8.3 KiB
C++
389 lines
8.3 KiB
C++
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
|
|
|
|
void clang_analyzer_eval(bool);
|
|
|
|
void array_value_a(void) {
|
|
int arr[2];
|
|
auto [a, b] = arr;
|
|
arr[0] = 0;
|
|
|
|
int x = a; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_value_b(void) {
|
|
int arr[] = {1, 2};
|
|
auto [a, b] = arr;
|
|
|
|
clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
|
|
|
|
int x = a; // no-warning
|
|
}
|
|
|
|
void array_value_c(void) {
|
|
int arr[3];
|
|
|
|
arr[1] = 1;
|
|
|
|
auto [a, b, c] = arr;
|
|
|
|
clang_analyzer_eval(b == arr[1]); // expected-warning{{TRUE}}
|
|
|
|
int y = b; // no-warning
|
|
int x = a; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_value_d(void) {
|
|
int arr[3];
|
|
|
|
arr[1] = 1;
|
|
|
|
auto [a, b, c] = arr;
|
|
|
|
clang_analyzer_eval(b == arr[1]); // expected-warning{{TRUE}}
|
|
|
|
int y = b; // no-warning
|
|
int x = c; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_value_e(void) {
|
|
int uninit[2];
|
|
int init[2] = {0};
|
|
|
|
uninit[0] = init[0];
|
|
|
|
auto [i, j] = init;
|
|
|
|
clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
|
|
|
|
int a = i; // no-warning
|
|
int b = j; // no-warning
|
|
}
|
|
|
|
void array_value_f(void) {
|
|
int uninit[2];
|
|
int init[2] = {0};
|
|
|
|
uninit[0] = init[0];
|
|
|
|
auto [i, j] = uninit;
|
|
|
|
clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
|
|
|
|
int a = i; // no-warning
|
|
int b = j; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_lref_a(void) {
|
|
int arr[2];
|
|
auto &[a, b] = arr;
|
|
int x = a; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_lref_b(void) {
|
|
int arr[] = {1, 2};
|
|
auto &[a, b] = arr;
|
|
|
|
clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
|
|
|
|
int x = a; // no-warning
|
|
}
|
|
|
|
void array_lref_c(void) {
|
|
int arr[2];
|
|
auto &[a, b] = arr;
|
|
|
|
arr[0] = 1;
|
|
|
|
clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
|
|
|
|
int x = a; // no-warning
|
|
int y = b; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_lref_d(void) {
|
|
int arr[3];
|
|
|
|
arr[1] = 1;
|
|
|
|
auto &[a, b, c] = arr;
|
|
|
|
clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
|
|
|
|
int y = b; // no-warning
|
|
int x = a; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_lref_e(void) {
|
|
int arr[3];
|
|
|
|
arr[1] = 1;
|
|
|
|
auto &[a, b, c] = arr;
|
|
|
|
clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
|
|
|
|
int y = b; // no-warning
|
|
int x = c; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_lref_f(void) {
|
|
int uninit[2];
|
|
int init[2] = {0};
|
|
|
|
uninit[0] = init[0];
|
|
|
|
auto &[i, j] = init;
|
|
|
|
clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
|
|
|
|
int a = i; // no-warning
|
|
int b = j; // no-warning
|
|
}
|
|
|
|
void array_lref_g(void) {
|
|
int uninit[2];
|
|
int init[2] = {0};
|
|
|
|
uninit[0] = init[0];
|
|
|
|
auto &[i, j] = uninit;
|
|
|
|
clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
|
|
|
|
int a = i; // no-warning
|
|
int b = j; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_rref_a(void) {
|
|
int arr[2];
|
|
auto &&[a, b] = arr;
|
|
int x = a; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_rref_b(void) {
|
|
int arr[] = {1, 2};
|
|
auto &&[a, b] = arr;
|
|
|
|
clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
|
|
|
|
int x = a; // no-warning
|
|
}
|
|
|
|
void array_rref_c(void) {
|
|
int arr[2];
|
|
auto &&[a, b] = arr;
|
|
|
|
arr[0] = 1;
|
|
|
|
clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
|
|
|
|
int x = a; // no-warning
|
|
int y = b; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_rref_d(void) {
|
|
int arr[3];
|
|
|
|
arr[1] = 1;
|
|
|
|
auto &&[a, b, c] = arr;
|
|
|
|
clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
|
|
|
|
int y = b; // no-warning
|
|
int x = a; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_rref_e(void) {
|
|
int arr[3];
|
|
|
|
arr[1] = 1;
|
|
|
|
auto &&[a, b, c] = arr;
|
|
|
|
clang_analyzer_eval(b == 1); // expected-warning{{TRUE}}
|
|
|
|
int y = b; // no-warning
|
|
int x = c; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_rref_f(void) {
|
|
int uninit[2];
|
|
int init[2] = {0};
|
|
|
|
uninit[0] = init[0];
|
|
|
|
auto &&[i, j] = init;
|
|
|
|
clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(j == 0); // expected-warning{{TRUE}}
|
|
|
|
int a = i; // no-warning
|
|
int b = j; // no-warning
|
|
}
|
|
|
|
void array_rref_g(void) {
|
|
int uninit[2];
|
|
int init[2] = {0};
|
|
|
|
uninit[0] = init[0];
|
|
|
|
auto &&[i, j] = uninit;
|
|
|
|
clang_analyzer_eval(i == 0); // expected-warning{{TRUE}}
|
|
|
|
int a = i; // no-warning
|
|
int b = j; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_change_a(void) {
|
|
int arr[] = {1, 2};
|
|
|
|
auto [a, b] = arr;
|
|
|
|
clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
|
|
a = 3;
|
|
clang_analyzer_eval(a == 3); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(arr[0] == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(arr[1] == 2); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
void array_change_b(void) {
|
|
int arr[] = {1, 2};
|
|
|
|
auto &[a, b] = arr;
|
|
|
|
clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
|
|
|
|
a = 3;
|
|
clang_analyzer_eval(a == 3); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(arr[0] == 3); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(arr[1] == 2); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
void array_small_a(void) {
|
|
int arr[5];
|
|
|
|
auto [a, b, c, d, e] = arr;
|
|
|
|
int x = e; // expected-warning{{Assigned value is uninitialized}}
|
|
}
|
|
|
|
void array_big_a(void) {
|
|
int arr[6];
|
|
|
|
auto [a, b, c, d, e, f] = arr;
|
|
|
|
// FIXME: These will be Undefined when we handle reading Undefined values from lazyCompoundVal.
|
|
clang_analyzer_eval(a == 1); // expected-warning{{UNKNOWN}}
|
|
clang_analyzer_eval(b == 2); // expected-warning{{UNKNOWN}}
|
|
clang_analyzer_eval(c == 3); // expected-warning{{UNKNOWN}}
|
|
clang_analyzer_eval(d == 4); // expected-warning{{UNKNOWN}}
|
|
clang_analyzer_eval(e == 5); // expected-warning{{UNKNOWN}}
|
|
clang_analyzer_eval(f == 6); // expected-warning{{UNKNOWN}}
|
|
}
|
|
|
|
struct S {
|
|
int a = 1;
|
|
int b = 2;
|
|
};
|
|
|
|
void non_pod_val(void) {
|
|
S arr[2];
|
|
|
|
auto [x, y] = arr;
|
|
|
|
clang_analyzer_eval(x.a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(x.b == 2); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(y.a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(y.b == 2); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
void non_pod_val_syntax_2(void) {
|
|
S arr[2];
|
|
|
|
auto [x, y](arr);
|
|
|
|
clang_analyzer_eval(x.a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(x.b == 2); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(y.a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(y.b == 2); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
void non_pod_lref(void) {
|
|
S arr[2];
|
|
|
|
auto &[x, y] = arr;
|
|
|
|
clang_analyzer_eval(x.a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(x.b == 2); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(y.a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(y.b == 2); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
void non_pod_rref(void) {
|
|
S arr[2];
|
|
|
|
auto &&[x, y] = arr;
|
|
|
|
clang_analyzer_eval(x.a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(x.b == 2); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(y.a == 1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(y.b == 2); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
struct SUD {
|
|
inline static int c = 0;
|
|
|
|
int a = 1;
|
|
int b = 2;
|
|
|
|
SUD() { ++c; };
|
|
|
|
SUD(const SUD ©) {
|
|
a = copy.a + 1;
|
|
b = copy.b + 1;
|
|
}
|
|
};
|
|
|
|
void non_pod_user_defined_val(void) {
|
|
SUD arr[2];
|
|
|
|
auto [x, y] = arr;
|
|
|
|
clang_analyzer_eval(x.a == 2); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(x.b == 3); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(y.a == 2); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(y.b == 3); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
void non_pod_user_defined_val_syntax_2(void) {
|
|
SUD::c = 0;
|
|
SUD arr[2];
|
|
|
|
auto [x, y](arr);
|
|
|
|
clang_analyzer_eval(SUD::c == 2); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(x.a == 2); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(x.b == 3); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(y.a == 2); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(y.b == 3); // expected-warning{{TRUE}}
|
|
}
|