diff options
| author | isuckatcs <65320245+isuckatcs@users.noreply.github.com> | 2022-06-08 23:23:07 +0200 |
|---|---|---|
| committer | isuckatcs <65320245+isuckatcs@users.noreply.github.com> | 2022-06-23 11:38:21 +0200 |
| commit | 8ef628088b54aebd4a8317ce3a0029e3283b3aa0 (patch) | |
| tree | d73e5368c207f4d1230b4f2ef932c14c9d966671 /clang/test/Analysis/uninit-structured-binding-array.cpp | |
| parent | 20b5f0c641c98e68d66dbaf882556e14f1fba9b8 (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.cpp | 294 |
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}} +} |
