brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.8 KiB · 057d002 Raw
581 lines · cpp
1// RUN: %clang_analyze_cc1 -Wno-ignored-reference-qualifiers -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s2 3#include "Inputs/system-header-simulator-cxx.h"4 5void clang_analyzer_eval(bool);6 7namespace std {8template <typename T>9struct tuple_size {10};11 12template <std::size_t I, typename T>13struct tuple_element {14};15 16// The std::pair in our system header simulator is not tuple-like, so a tuple-like mock is created here17template <typename T1, typename T2>18struct mock_pair {19  T1 first;20  T2 second;21};22template <typename T1, typename T2>23struct tuple_size<mock_pair<T1, T2>> {24  static const std::size_t value = 2;25};26 27template <typename T1, typename T2>28struct tuple_element<0, mock_pair<T1, T2>> {29  using type = T1;30};31 32template <typename T1, typename T2>33struct tuple_element<1, mock_pair<T1, T2>> {34  using type = T2;35};36 37template <std::size_t I, class T>38using tuple_element_t = typename tuple_element<I, T>::type;39 40template <std::size_t I, class T1, class T2>41constexpr std::tuple_element_t<I, std::mock_pair<T1, T2>> &42get(std::mock_pair<T1, T2> &p) noexcept {43  if (I == 0)44    return p.first;45  else46    return p.second;47}48 49template <std::size_t I, class T1, class T2>50constexpr const std::tuple_element_t<I, std::mock_pair<T1, T2>> &51get(const std::mock_pair<T1, T2> &p) noexcept {52  if (I == 0)53    return p.first;54  else55    return p.second;56}57 58template <std::size_t I, class T1, class T2>59constexpr std::tuple_element_t<I, std::mock_pair<T1, T2>> &&60get(std::mock_pair<T1, T2> &&p) noexcept {61 62  if (I == 0)63    return static_cast<std::tuple_element_t<I, std::mock_pair<T1, T2>> &&>(p.first);64  else65    return static_cast<std::tuple_element_t<I, std::mock_pair<T1, T2>> &&>(p.second);66}67 68template <std::size_t I, class T1, class T2>69constexpr const std::tuple_element_t<I, std::mock_pair<T1, T2>> &&70get(const std::mock_pair<T1, T2> &&p) noexcept {71  if (I == 0)72    return static_cast<std::tuple_element_t<I, std::mock_pair<T1, T2>> &&>(p.first);73  else74    return static_cast<std::tuple_element_t<I, std::mock_pair<T1, T2>> &&>(p.second);75}76 77} // namespace std78// A utility that generates a tuple-like struct with 2 fields79//  of the same type. The fields are 'first' and 'second'80#define GENERATE_TUPLE_LIKE_STRUCT(name, element_type) \81  struct name {                                        \82    element_type first;                                \83    element_type second;                               \84  };                                                   \85                                                       \86  namespace std {                                      \87  template <>                                          \88  struct tuple_size<name> {                            \89    static const std::size_t value = 2;                \90  };                                                   \91                                                       \92  template <std::size_t I>                             \93  struct tuple_element<I, name> {                      \94    using type = element_type;                         \95  };                                                   \96  }97 98void non_user_defined_by_value(void) {99  std::mock_pair<int, int> p = {1, 2};100 101  auto [u, v] = p;102 103  clang_analyzer_eval(u == 1); // expected-warning{{TRUE}}104  clang_analyzer_eval(v == 2); // expected-warning{{TRUE}}105 106  int x = u;107  u = 10;108  int y = u;109 110  clang_analyzer_eval(x == 1);  // expected-warning{{TRUE}}111  clang_analyzer_eval(u == 10); // expected-warning{{TRUE}}112 113  clang_analyzer_eval(y == 10);      // expected-warning{{TRUE}}114  clang_analyzer_eval(p.first == 1); // expected-warning{{TRUE}}115 116  p.first = 5;117 118  clang_analyzer_eval(u == 10); // expected-warning{{TRUE}}119}120 121void non_user_defined_by_lref(void) {122  std::mock_pair<int, int> p = {1, 2};123 124  auto &[u, v] = p;125 126  int x = u;127  u = 10;128  int y = u;129 130  clang_analyzer_eval(x == 1);  // expected-warning{{TRUE}}131  clang_analyzer_eval(u == 10); // expected-warning{{TRUE}}132 133  clang_analyzer_eval(y == 10);       // expected-warning{{TRUE}}134  clang_analyzer_eval(p.first == 10); // expected-warning{{TRUE}}135 136  clang_analyzer_eval(v == 2);        // expected-warning{{TRUE}}137  clang_analyzer_eval(p.second == 2); // expected-warning{{TRUE}}138 139  p.first = 5;140 141  clang_analyzer_eval(u == 5); // expected-warning{{TRUE}}142}143 144void non_user_defined_by_rref(void) {145  std::mock_pair<int, int> p = {1, 2};146 147  auto &&[u, v] = p;148 149  int x = u;150  u = 10;151  int y = u;152 153  clang_analyzer_eval(x == 1);  // expected-warning{{TRUE}}154  clang_analyzer_eval(u == 10); // expected-warning{{TRUE}}155 156  clang_analyzer_eval(y == 10);       // expected-warning{{TRUE}}157  clang_analyzer_eval(p.first == 10); // expected-warning{{TRUE}}158 159  clang_analyzer_eval(v == 2);        // expected-warning{{TRUE}}160  clang_analyzer_eval(p.second == 2); // expected-warning{{TRUE}}161 162  p.first = 5;163 164  clang_analyzer_eval(u == 5); // expected-warning{{TRUE}}165}166 167GENERATE_TUPLE_LIKE_STRUCT(Test, int);168 169template <std::size_t I>170int get(Test t) {171  if (I == 0) {172    t.second = 10;173    return t.first;174  } else {175    t.first = 20;176    return t.second;177  }178}179 180void user_defined_get_val_by_val(void) {181  Test p{1, 2};182  auto [u, v] = p;183 184  clang_analyzer_eval(u == 1); // expected-warning{{TRUE}}185 186  u = 8;187 188  int x = u;189 190  clang_analyzer_eval(x == 8); // expected-warning{{TRUE}}191 192  clang_analyzer_eval(u == 8); // expected-warning{{TRUE}}193  clang_analyzer_eval(v == 2); // expected-warning{{TRUE}}194 195  clang_analyzer_eval(p.first == 1);  // expected-warning{{TRUE}}196  clang_analyzer_eval(p.second == 2); // expected-warning{{TRUE}}197 198  p.first = 5;199 200  clang_analyzer_eval(u == 8);       // expected-warning{{TRUE}}201  clang_analyzer_eval(p.first == 5); // expected-warning{{TRUE}}202}203 204GENERATE_TUPLE_LIKE_STRUCT(Test2, int);205 206template <std::size_t I>207int get(Test2 &t) {208  if (I == 0) {209    t.second = 10;210    return t.first;211  } else {212    t.first = 20;213    return t.second;214  }215}216 217void user_defined_get_val_by_lref(void) {218  Test2 p{1, 2};219 220  auto &[u, v] = p;221 222  clang_analyzer_eval(u == 1);  // expected-warning{{TRUE}}223  clang_analyzer_eval(v == 10); // expected-warning{{TRUE}}224 225  u = 8;226 227  int x = u;228 229  clang_analyzer_eval(x == 8); // expected-warning{{TRUE}}230 231  clang_analyzer_eval(u == 8);  // expected-warning{{TRUE}}232  clang_analyzer_eval(v == 10); // expected-warning{{TRUE}}233 234  clang_analyzer_eval(p.first == 20);  // expected-warning{{TRUE}}235  clang_analyzer_eval(p.second == 10); // expected-warning{{TRUE}}236 237  p.first = 5;238 239  clang_analyzer_eval(u == 8);       // expected-warning{{TRUE}}240  clang_analyzer_eval(p.first == 5); // expected-warning{{TRUE}}241}242 243void user_defined_get_val_by_rref(void) {244  Test2 p{1, 2};245 246  auto &&[u, v] = p;247 248  clang_analyzer_eval(u == 1);  // expected-warning{{TRUE}}249  clang_analyzer_eval(v == 10); // expected-warning{{TRUE}}250 251  u = 8;252 253  int x = u;254 255  clang_analyzer_eval(x == 8); // expected-warning{{TRUE}}256 257  clang_analyzer_eval(u == 8);  // expected-warning{{TRUE}}258  clang_analyzer_eval(v == 10); // expected-warning{{TRUE}}259 260  clang_analyzer_eval(p.first == 20);  // expected-warning{{TRUE}}261  clang_analyzer_eval(p.second == 10); // expected-warning{{TRUE}}262 263  p.first = 5;264 265  clang_analyzer_eval(u == 8);       // expected-warning{{TRUE}}266  clang_analyzer_eval(p.first == 5); // expected-warning{{TRUE}}267}268 269struct MixedTest {270  int x;271  char &&y;272  int &z;273};274 275namespace std {276template <>277struct tuple_size<MixedTest> {278  static const std::size_t value = 3;279};280 281template <>282struct tuple_element<0, MixedTest> {283  using type = int;284};285 286template <>287struct tuple_element<1, MixedTest> {288  using type = char &&;289};290 291template <>292struct tuple_element<2, MixedTest> {293  using type = int &;294};295 296template <std::size_t I, typename T>297using tuple_element_t = typename tuple_element<I, T>::type;298 299} // namespace std300 301template <std::size_t I>302const std::tuple_element_t<I, MixedTest> &get(const MixedTest &t) {}303 304template <>305const std::tuple_element_t<0, MixedTest> &get<0>(const MixedTest &t) {306  return t.x;307}308 309template <>310const std::tuple_element_t<1, MixedTest> &get<1>(const MixedTest &t) {311  return t.y;312}313 314template <>315const std::tuple_element_t<2, MixedTest> &get<2>(const MixedTest &t) {316  return t.z;317}318 319void mixed_type_cref(void) {320  int x = 1;321  char y = 2;322  int z = 3;323 324  MixedTest m{x, std::move(y), z};325  const auto &[a, b, c] = m;326 327  clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}328  clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}329  clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}330 331  clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}332  clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}333  clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}334}335 336template <std::size_t I>337std::tuple_element_t<I, MixedTest> &get(MixedTest &t) {}338 339template <>340std::tuple_element_t<0, MixedTest> &get<0>(MixedTest &t) {341  return t.x;342}343 344template <>345std::tuple_element_t<1, MixedTest> &get<1>(MixedTest &t) {346  return t.y;347}348 349template <>350std::tuple_element_t<2, MixedTest> &get<2>(MixedTest &t) {351  return t.z;352}353 354void mixed_type_lref(void) {355  int x = 1;356  char y = 2;357  int z = 3;358 359  MixedTest m{x, std::move(y), z};360  auto &[a, b, c] = m;361 362  a = 4;363  b = 5;364  c = 6;365 366  clang_analyzer_eval(get<0>(m) == 4); // expected-warning{{TRUE}}367  clang_analyzer_eval(get<1>(m) == 5); // expected-warning{{TRUE}}368  clang_analyzer_eval(get<2>(m) == 6); // expected-warning{{TRUE}}369 370  clang_analyzer_eval(get<0>(m) == 4); // expected-warning{{TRUE}}371  clang_analyzer_eval(get<1>(m) == 5); // expected-warning{{TRUE}}372  clang_analyzer_eval(get<2>(m) == 6); // expected-warning{{TRUE}}373 374  clang_analyzer_eval(z == 6); // expected-warning{{TRUE}}375}376 377void mixed_type_rref(void) {378  int x = 1;379  char y = 2;380  int z = 3;381 382  MixedTest m{x, std::move(y), z};383  auto &&[a, b, c] = m;384 385  a = 4;386  b = 5;387  c = 6;388 389  clang_analyzer_eval(get<0>(m) == 4); // expected-warning{{TRUE}}390  clang_analyzer_eval(get<1>(m) == 5); // expected-warning{{TRUE}}391  clang_analyzer_eval(get<2>(m) == 6); // expected-warning{{TRUE}}392 393  clang_analyzer_eval(get<0>(m) == 4); // expected-warning{{TRUE}}394  clang_analyzer_eval(get<1>(m) == 5); // expected-warning{{TRUE}}395  clang_analyzer_eval(get<2>(m) == 6); // expected-warning{{TRUE}}396 397  clang_analyzer_eval(z == 6); // expected-warning{{TRUE}}398}399 400void ref_val(void) {401  int i = 1, j = 2;402  std::mock_pair<int &, int &> p{i, j};403 404  auto [a, b] = p;405  clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}406  clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}407 408  a = 3;409  b = 4;410 411  clang_analyzer_eval(p.first == 3);  // expected-warning{{TRUE}}412  clang_analyzer_eval(p.second == 4); // expected-warning{{TRUE}}413 414  clang_analyzer_eval(a == 3); // expected-warning{{TRUE}}415  clang_analyzer_eval(b == 4); // expected-warning{{TRUE}}416}417 418struct Small_Non_POD {419  int i;420  int j;421};422 423void non_user_defined_small_non_pod_by_value(void) {424  std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {1, 2}};425 426  auto [a, b] = p;427 428  clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}429  clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}430 431  clang_analyzer_eval(b.i == 1); // expected-warning{{TRUE}}432  clang_analyzer_eval(b.j == 2); // expected-warning{{TRUE}}433 434  a.i = 3;435  a.j = 4;436 437  b.i = 5;438  b.j = 6;439 440  clang_analyzer_eval(a.i == 3); // expected-warning{{TRUE}}441  clang_analyzer_eval(a.j == 4); // expected-warning{{TRUE}}442 443  clang_analyzer_eval(b.i == 5); // expected-warning{{TRUE}}444  clang_analyzer_eval(b.j == 6); // expected-warning{{TRUE}}445 446  clang_analyzer_eval(p.first.i == 1); // expected-warning{{TRUE}}447  clang_analyzer_eval(p.first.j == 2); // expected-warning{{TRUE}}448 449  clang_analyzer_eval(p.second.i == 1); // expected-warning{{TRUE}}450  clang_analyzer_eval(p.second.j == 2); // expected-warning{{TRUE}}451}452 453void non_user_defined_small_non_pod_by_lref(void) {454  std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {1, 2}};455 456  auto &[a, b] = p;457 458  clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}459  clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}460 461  clang_analyzer_eval(b.i == 1); // expected-warning{{TRUE}}462  clang_analyzer_eval(b.j == 2); // expected-warning{{TRUE}}463 464  a.i = 3;465  a.j = 4;466 467  b.i = 5;468  b.j = 6;469 470  clang_analyzer_eval(a.i == 3); // expected-warning{{TRUE}}471  clang_analyzer_eval(a.j == 4); // expected-warning{{TRUE}}472 473  clang_analyzer_eval(b.i == 5); // expected-warning{{TRUE}}474  clang_analyzer_eval(b.j == 6); // expected-warning{{TRUE}}475 476  clang_analyzer_eval(p.first.i == 3); // expected-warning{{TRUE}}477  clang_analyzer_eval(p.first.j == 4); // expected-warning{{TRUE}}478 479  clang_analyzer_eval(p.second.i == 5); // expected-warning{{TRUE}}480  clang_analyzer_eval(p.second.j == 6); // expected-warning{{TRUE}}481}482 483void non_user_defined_small_non_pod_by_rref(void) {484  std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {1, 2}};485 486  auto &&[a, b] = p;487 488  clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}489  clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}490 491  clang_analyzer_eval(b.i == 1); // expected-warning{{TRUE}}492  clang_analyzer_eval(b.j == 2); // expected-warning{{TRUE}}493 494  a.i = 3;495  a.j = 4;496 497  b.i = 5;498  b.j = 6;499 500  clang_analyzer_eval(a.i == 3); // expected-warning{{TRUE}}501  clang_analyzer_eval(a.j == 4); // expected-warning{{TRUE}}502 503  clang_analyzer_eval(b.i == 5); // expected-warning{{TRUE}}504  clang_analyzer_eval(b.j == 6); // expected-warning{{TRUE}}505 506  clang_analyzer_eval(p.first.i == 3); // expected-warning{{TRUE}}507  clang_analyzer_eval(p.first.j == 4); // expected-warning{{TRUE}}508 509  clang_analyzer_eval(p.second.i == 5); // expected-warning{{TRUE}}510  clang_analyzer_eval(p.second.j == 6); // expected-warning{{TRUE}}511}512 513GENERATE_TUPLE_LIKE_STRUCT(Uninit, int);514template <std::size_t I>515int &get(Uninit &&t) {516  if (I == 0) {517    return t.first;518  } else {519    return t.second;520  }521}522 523void uninit_a(void) {524  Uninit u;525 526  auto [a, b] = u;527 528  int x = a; // expected-warning{{Assigned value is uninitialized}}529}530 531void uninit_b(void) {532  Uninit u;533 534  auto [a, b] = u;535 536  int x = b; // expected-warning{{Assigned value is uninitialized}}537}538 539GENERATE_TUPLE_LIKE_STRUCT(UninitCall, int);540template <std::size_t I>541int get(UninitCall t) {542  if (I == 0) {543    return t.first;544  } else {545    return t.second;546  }547}548 549void uninit_call(void) {550  UninitCall u;551 552  auto [a, b] = u;553 554  int x = a;555  // expected-warning@543{{Undefined or garbage value returned to caller}}556}557 558void syntax_2() {559  std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {3, 4}};560 561  auto [a, b]{p};562 563  clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}564  clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}565 566  clang_analyzer_eval(b.i == 3); // expected-warning{{TRUE}}567  clang_analyzer_eval(b.j == 4); // expected-warning{{TRUE}}568}569 570void syntax_3() {571  std::mock_pair<Small_Non_POD, Small_Non_POD> p{{1, 2}, {3, 4}};572 573  auto [a, b](p);574 575  clang_analyzer_eval(a.i == 1); // expected-warning{{TRUE}}576  clang_analyzer_eval(a.j == 2); // expected-warning{{TRUE}}577 578  clang_analyzer_eval(b.i == 3); // expected-warning{{TRUE}}579  clang_analyzer_eval(b.j == 4); // expected-warning{{TRUE}}580}581