brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.7 KiB · dfd1f95 Raw
371 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s2 3void clang_analyzer_eval(bool);4 5void array_init() {6  int arr[] = {1, 2, 3, 4, 5};7 8  auto [a, b, c, d, e] = arr;9 10  clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}11  clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}12  clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}13  clang_analyzer_eval(d == 4); // expected-warning{{TRUE}}14  clang_analyzer_eval(e == 5); // expected-warning{{TRUE}}15}16 17void array_uninit() {18  int arr[5];19 20  auto [a, b, c, d, e] = arr;21 22  int x = e; // expected-warning{{Assigned value is uninitialized}}23}24 25void lambda_init() {26  int arr[] = {1, 2, 3, 4, 5};27 28  auto l = [arr] { return arr[0]; }();29  clang_analyzer_eval(l == 1); // expected-warning{{TRUE}}30 31  l = [arr] { return arr[1]; }();32  clang_analyzer_eval(l == 2); // expected-warning{{TRUE}}33 34  l = [arr] { return arr[2]; }();35  clang_analyzer_eval(l == 3); // expected-warning{{TRUE}}36 37  l = [arr] { return arr[3]; }();38  clang_analyzer_eval(l == 4); // expected-warning{{TRUE}}39 40  l = [arr] { return arr[4]; }();41  clang_analyzer_eval(l == 5); // expected-warning{{TRUE}}42}43 44void lambda_uninit() {45  int arr[5];46 47  // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal48  int l = [arr] { return arr[0]; }();49  clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}50 51  l = [arr] { return arr[1]; }();52  clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}53 54  l = [arr] { return arr[2]; }();55  clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}56 57  l = [arr] { return arr[3]; }();58  clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}59 60  l = [arr] { return arr[4]; }();61  clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}62}63 64struct S {65  int arr[5];66};67 68void copy_ctor_init() {69  S orig;70  orig.arr[0] = 1;71  orig.arr[1] = 2;72  orig.arr[2] = 3;73  orig.arr[3] = 4;74  orig.arr[4] = 5;75 76  S copy = orig;77  clang_analyzer_eval(copy.arr[0] == 1); // expected-warning{{TRUE}}78  clang_analyzer_eval(copy.arr[1] == 2); // expected-warning{{TRUE}}79  clang_analyzer_eval(copy.arr[2] == 3); // expected-warning{{TRUE}}80  clang_analyzer_eval(copy.arr[3] == 4); // expected-warning{{TRUE}}81  clang_analyzer_eval(copy.arr[4] == 5); // expected-warning{{TRUE}}82}83 84void copy_ctor_uninit() {85  S orig;86 87  S copy = orig;88 89  // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal.90  // If the struct is not considered a small struct, instead of a copy, we store a lazy compound value.91  // As the struct has an array data member, it is not considered small.92  clang_analyzer_eval(copy.arr[0]); // expected-warning{{UNKNOWN}}93  clang_analyzer_eval(copy.arr[1]); // expected-warning{{UNKNOWN}}94  clang_analyzer_eval(copy.arr[2]); // expected-warning{{UNKNOWN}}95  clang_analyzer_eval(copy.arr[3]); // expected-warning{{UNKNOWN}}96  clang_analyzer_eval(copy.arr[4]); // expected-warning{{UNKNOWN}}97}98 99void move_ctor_init() {100  S orig;101  orig.arr[0] = 1;102  orig.arr[1] = 2;103  orig.arr[2] = 3;104  orig.arr[3] = 4;105  orig.arr[4] = 5;106 107  S moved = (S &&) orig;108 109  clang_analyzer_eval(moved.arr[0] == 1); // expected-warning{{TRUE}}110  clang_analyzer_eval(moved.arr[1] == 2); // expected-warning{{TRUE}}111  clang_analyzer_eval(moved.arr[2] == 3); // expected-warning{{TRUE}}112  clang_analyzer_eval(moved.arr[3] == 4); // expected-warning{{TRUE}}113  clang_analyzer_eval(moved.arr[4] == 5); // expected-warning{{TRUE}}114}115 116void move_ctor_uninit() {117  S orig;118 119  S moved = (S &&) orig;120 121  // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal.122  clang_analyzer_eval(moved.arr[0]); // expected-warning{{UNKNOWN}}123  clang_analyzer_eval(moved.arr[1]); // expected-warning{{UNKNOWN}}124  clang_analyzer_eval(moved.arr[2]); // expected-warning{{UNKNOWN}}125  clang_analyzer_eval(moved.arr[3]); // expected-warning{{UNKNOWN}}126  clang_analyzer_eval(moved.arr[4]); // expected-warning{{UNKNOWN}}127}128 129// The struct has a user defined copy and move ctor, which allow us to130// track the values more precisely when an array of this struct is being131// copy/move initialized by ArrayInitLoopExpr.132struct S2 {133  inline static int c = 0;134  int i;135 136  S2() : i(++c) {}137 138  S2(const S2 &copy) {139    i = copy.i + 1;140  }141 142  S2(S2 &&move) {143    i = move.i + 2;144  }145};146 147void array_init_non_pod() {148  S2::c = 0;149  S2 arr[4];150 151  auto [a, b, c, d] = arr;152 153  clang_analyzer_eval(a.i == 2); // expected-warning{{TRUE}}154  clang_analyzer_eval(b.i == 3); // expected-warning{{TRUE}}155  clang_analyzer_eval(c.i == 4); // expected-warning{{TRUE}}156  clang_analyzer_eval(d.i == 5); // expected-warning{{TRUE}}157}158 159struct S3 {160  int i;161};162 163// The duplicate is required to emit a warning at 2 different places. 164struct S3_duplicate {165  int i;166};167 168void array_uninit_non_pod() {169  S3 arr[1];170 171  auto [a] = arr; // expected-warning@159{{ in implicit constructor is uninitialized}}172}173 174void lambda_init_non_pod() {175  S2::c = 0;176  S2 arr[4];177 178  auto l = [arr] { return arr[0].i; }();179  clang_analyzer_eval(l == 2); // expected-warning{{TRUE}}180 181  l = [arr] { return arr[1].i; }();182  clang_analyzer_eval(l == 3); // expected-warning{{TRUE}}183 184  l = [arr] { return arr[2].i; }();185  clang_analyzer_eval(l == 4); // expected-warning{{TRUE}}186 187  l = [arr] { return arr[3].i; }();188  clang_analyzer_eval(l == 5); // expected-warning{{TRUE}}189}190 191void lambda_uninit_non_pod() {192  S3_duplicate arr[4];193 194  int l = [arr] { return arr[3].i; }(); // expected-warning@164{{ in implicit constructor is uninitialized }}195}196 197// If this struct is being copy/move constructed by the implicit ctors, ArrayInitLoopExpr198// is responsible for the initialization of 'arr' by copy/move constructing each of the199// elements.200struct S5 {201  S2 arr[4];202};203 204void copy_ctor_init_non_pod() {205  S2::c = 0;206  S5 orig;207 208  S5 copy = orig;209  clang_analyzer_eval(copy.arr[0].i == 2); // expected-warning{{TRUE}}210  clang_analyzer_eval(copy.arr[1].i == 3); // expected-warning{{TRUE}}211  clang_analyzer_eval(copy.arr[2].i == 4); // expected-warning{{TRUE}}212  clang_analyzer_eval(copy.arr[3].i == 5); // expected-warning{{TRUE}}213}214 215void move_ctor_init_non_pod() {216  S2::c = 0;217  S5 orig;218 219  S5 moved = (S5 &&) orig;220 221  clang_analyzer_eval(moved.arr[0].i == 3); // expected-warning{{TRUE}}222  clang_analyzer_eval(moved.arr[1].i == 4); // expected-warning{{TRUE}}223  clang_analyzer_eval(moved.arr[2].i == 5); // expected-warning{{TRUE}}224  clang_analyzer_eval(moved.arr[3].i == 6); // expected-warning{{TRUE}}225}226 227//Note: This is the only solution I could find to check the values without 228// crashing clang. For more details on the crash see Issue #57135.229void lambda_capture_multi_array() {230  S3 arr[2][2] = {1,2,3,4};231 232  {233    int x = [arr] { return arr[0][0].i; }();234    clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}235  }236 237  {238    int x = [arr] { return arr[0][1].i; }();239    clang_analyzer_eval(x == 2); // expected-warning{{TRUE}}240  }241 242  {243    int x = [arr] { return arr[1][0].i; }();244    clang_analyzer_eval(x == 3); // expected-warning{{TRUE}}245  }246 247  {248    int x = [arr] { return arr[1][1].i; }();249    clang_analyzer_eval(x == 4); // expected-warning{{TRUE}}250  }251}252 253// This struct will force constructor inlining in MultiWrapper.254struct UserDefinedCtor {255  int i;256  UserDefinedCtor() {}257  UserDefinedCtor(const UserDefinedCtor &copy) {258    int j = 1;259    i = copy.i;260  }261};262 263struct MultiWrapper {264  UserDefinedCtor arr[2][2];265};266 267void copy_ctor_multi() {268  MultiWrapper MW;269 270  MW.arr[0][0].i = 0;271  MW.arr[0][1].i = 1;272  MW.arr[1][0].i = 2;273  MW.arr[1][1].i = 3;274 275  MultiWrapper MWCopy = MW;276  277  clang_analyzer_eval(MWCopy.arr[0][0].i == 0); // expected-warning{{TRUE}}278  clang_analyzer_eval(MWCopy.arr[0][1].i == 1); // expected-warning{{TRUE}}279  clang_analyzer_eval(MWCopy.arr[1][0].i == 2); // expected-warning{{TRUE}}280  clang_analyzer_eval(MWCopy.arr[1][1].i == 3); // expected-warning{{TRUE}}281} 282 283void move_ctor_multi() {284  MultiWrapper MW;285 286  MW.arr[0][0].i = 0;287  MW.arr[0][1].i = 1;288  MW.arr[1][0].i = 2;289  MW.arr[1][1].i = 3;290 291  MultiWrapper MWMove = (MultiWrapper &&) MW;292  293  clang_analyzer_eval(MWMove.arr[0][0].i == 0); // expected-warning{{TRUE}}294  clang_analyzer_eval(MWMove.arr[0][1].i == 1); // expected-warning{{TRUE}}295  clang_analyzer_eval(MWMove.arr[1][0].i == 2); // expected-warning{{TRUE}}296  clang_analyzer_eval(MWMove.arr[1][1].i == 3); // expected-warning{{TRUE}}297} 298 299void structured_binding_multi() {300  S3 arr[2][2] = {1,2,3,4};301 302  auto [a,b] = arr;303 304  clang_analyzer_eval(a[0].i == 1); // expected-warning{{TRUE}}305  clang_analyzer_eval(a[1].i == 2); // expected-warning{{TRUE}}306  clang_analyzer_eval(b[0].i == 3); // expected-warning{{TRUE}}307  clang_analyzer_eval(b[1].i == 4); // expected-warning{{TRUE}}308}309 310// This snippet used to crash311namespace crash {312 313struct S314{315  int x;316  S() { x = 1; }317};318 319void no_crash() {320  S arr[0];321  int n = 1;322 323  auto l = [arr, n] { return n; };324 325  int x = l();326  clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}327 328  // FIXME: This should be 'Undefined'.329  clang_analyzer_eval(arr[0].x); // expected-warning{{UNKNOWN}}330}331 332} // namespace crash333 334namespace array_subscript_initializer {335struct S {336  int x;337};338 339void no_crash() {340  S arr[][2] = {{1, 2}};341 342  const auto [a, b] = arr[0]; // no-crash343 344  clang_analyzer_eval(a.x == 1); // expected-warning{{TRUE}}345  clang_analyzer_eval(b.x == 2); // expected-warning{{TRUE}}346}347} // namespace array_subscript_initializer348 349namespace iterator_initializer {350struct S {351  int x;352};353 354void no_crash() {355  S arr[][2] = {{1, 2}, {3, 4}};356 357  int i = 0;358  for (const auto [a, b] : arr) { // no-crash359    if (i == 0) {360      clang_analyzer_eval(a.x == 1); // expected-warning{{TRUE}}361      clang_analyzer_eval(b.x == 2); // expected-warning{{TRUE}}362    } else {363      clang_analyzer_eval(a.x == 3); // expected-warning{{TRUE}}364      clang_analyzer_eval(b.x == 4); // expected-warning{{TRUE}}365    }366 367    ++i;368  }369}370} // namespace iterator_initializer371