summaryrefslogtreecommitdiff
path: root/clang/test/Analysis/uninit-structured-binding-array.cpp
diff options
context:
space:
mode:
authorisuckatcs <65320245+isuckatcs@users.noreply.github.com>2022-06-08 23:23:07 +0200
committerisuckatcs <65320245+isuckatcs@users.noreply.github.com>2022-06-23 11:38:21 +0200
commit8ef628088b54aebd4a8317ce3a0029e3283b3aa0 (patch)
treed73e5368c207f4d1230b4f2ef932c14c9d966671 /clang/test/Analysis/uninit-structured-binding-array.cpp
parent20b5f0c641c98e68d66dbaf882556e14f1fba9b8 (diff)
[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
Diffstat (limited to 'clang/test/Analysis/uninit-structured-binding-array.cpp')
-rw-r--r--clang/test/Analysis/uninit-structured-binding-array.cpp294
1 files changed, 294 insertions, 0 deletions
diff --git a/clang/test/Analysis/uninit-structured-binding-array.cpp b/clang/test/Analysis/uninit-structured-binding-array.cpp
new file mode 100644
index 000000000000..b727cb49daaa
--- /dev/null
+++ b/clang/test/Analysis/uninit-structured-binding-array.cpp
@@ -0,0 +1,294 @@
+// 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}}
+}