Files
clang-p2996/clang/test/Analysis/uninit-structured-binding-array.cpp
isuckatcs 8ef628088b [analyzer] Structured binding to arrays
Introducing structured binding to data members and more.
To handle binding to arrays, ArrayInitLoopExpr is also
evaluated, which enables the analyzer to store information
in two more cases. These are:
  - when a lambda-expression captures an array by value
  - in the implicit copy/move constructor for a class
    with an array member

Differential Revision: https://reviews.llvm.org/D126613
2022-06-23 11:38:21 +02:00

295 lines
6.2 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 garbage or undefined}}
}
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 garbage or undefined}}
}
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 garbage or undefined}}
}
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 garbage or undefined}}
}
void array_lref_a(void) {
int arr[2];
auto &[a, b] = arr;
int x = a; // expected-warning{{Assigned value is garbage or undefined}}
}
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 garbage or undefined}}
}
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 garbage or undefined}}
}
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 garbage or undefined}}
}
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 garbage or undefined}}
}
void array_rref_a(void) {
int arr[2];
auto &&[a, b] = arr;
int x = a; // expected-warning{{Assigned value is garbage or undefined}}
}
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 garbage or undefined}}
}
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 garbage or undefined}}
}
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 garbage or undefined}}
}
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 garbage or undefined}}
}
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 garbage or undefined}}
}
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}}
}