brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.8 KiB · 344de80 Raw
415 lines · cpp
1// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -verify %s -o %t.report2// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBSTDCPP -verify %s -o %t.report3 4// We do NOT model libcxx03 implementation, but the analyzer should still5// not crash.6// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -verify %s -o %t.report7// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -DEMULATE_LIBSTDCPP -verify %s -o %t.report8// RUN: rm -rf %t.report9 10void clang_analyzer_eval(bool);11 12// Faking std::call_once implementation.13namespace std {14 15// Fake std::function implementation.16template <typename>17class function;18class function_base {19 public:20  long field;21};22template <typename R, typename... P>23class function<R(P...)> : function_base {24 public:25   R operator()(P...) const {26 27     // Read from a super-class necessary to reproduce a crash.28     bool a = field;29   }30};31 32#ifndef EMULATE_LIBSTDCPP33typedef struct once_flag_s {34  unsigned long __state_ = 0;35} once_flag;36#else37typedef struct once_flag_s {38  int _M_once = 0;39} once_flag;40#endif41 42#ifndef EMULATE_LIBCXX0343template <class Callable, class... Args>44void call_once(once_flag &o, Callable&& func, Args&&... args) {};45#else46template <class Callable, class... Args> // libcxx03 call_once47void call_once(once_flag &o, Callable func, Args&&... args) {};48#endif49 50} // namespace std51 52// Check with Lambdas.53void test_called_warning() {54  std::once_flag g_initialize;55  int z;56 57  std::call_once(g_initialize, [&] {58    int *x = nullptr;59#ifndef EMULATE_LIBCXX0360    int y = *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}61#endif62    z = 200;63  });64}65 66void test_called_on_path_inside_no_warning() {67  std::once_flag g_initialize;68 69  int *x = nullptr;70  int y = 100;71  int z;72 73  std::call_once(g_initialize, [&] {74    z = 200;75    x = &z;76  });77 78#ifndef EMULATE_LIBCXX0379  *x = 100; // no-warning80  clang_analyzer_eval(z == 100); // expected-warning{{TRUE}}81#endif82}83 84void test_called_on_path_no_warning() {85  std::once_flag g_initialize;86 87  int *x = nullptr;88  int y = 100;89 90  std::call_once(g_initialize, [&] {91    x = &y;92  });93 94#ifndef EMULATE_LIBCXX0395  *x = 100; // no-warning96#else97  *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}98#endif99}100 101void test_called_on_path_warning() {102  std::once_flag g_initialize;103 104  int y = 100;105  int *x = &y;106 107  std::call_once(g_initialize, [&] {108    x = nullptr;109  });110 111#ifndef EMULATE_LIBCXX03112  *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}113#endif114}115 116void test_called_once_warning() {117  std::once_flag g_initialize;118 119  int *x = nullptr;120  int y = 100;121 122  std::call_once(g_initialize, [&] {123    x = nullptr;124  });125 126  std::call_once(g_initialize, [&] {127    x = &y;128  });129 130#ifndef EMULATE_LIBCXX03131  *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}132#endif133}134 135void test_called_once_no_warning() {136  std::once_flag g_initialize;137 138  int *x = nullptr;139  int y = 100;140 141  std::call_once(g_initialize, [&] {142    x = &y;143  });144 145  std::call_once(g_initialize, [&] {146    x = nullptr;147  });148 149#ifndef EMULATE_LIBCXX03150  *x = 100; // no-warning151#endif152}153 154static int global = 0;155void funcPointer() {156  global = 1;157}158 159void test_func_pointers() {160  static std::once_flag flag;161  std::call_once(flag, &funcPointer);162#ifndef EMULATE_LIBCXX03163  clang_analyzer_eval(global == 1); // expected-warning{{TRUE}}164#endif165}166 167template <class _Fp>168class function; // undefined169template <class _Rp, class... _ArgTypes>170struct function<_Rp(_ArgTypes...)> {171  _Rp operator()(_ArgTypes...) const {};172  template <class _Fp>173  function(_Fp) {};174};175 176// Note: currently we do not support calls to std::function,177// but the analyzer should not crash either.178void test_function_objects_warning() {179  int x = 0;180  int *y = &x;181 182  std::once_flag flag;183 184  function<void()> func = [&]() {185    y = nullptr;186  };187 188  std::call_once(flag, func);189 190  func();191  int z = *y;192}193 194void test_param_passing_lambda() {195  std::once_flag flag;196  int x = 120;197  int y = 0;198 199  std::call_once(flag, [&](int p) {200    y = p;201  },202                 x);203 204#ifndef EMULATE_LIBCXX03205  clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}206#endif207}208 209void test_param_passing_lambda_false() {210  std::once_flag flag;211  int x = 120;212 213  std::call_once(flag, [&](int p) {214    x = 0;215  },216                 x);217 218#ifndef EMULATE_LIBCXX03219  clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}220#endif221}222 223void test_param_passing_stored_lambda() {224  std::once_flag flag;225  int x = 120;226  int y = 0;227 228  auto lambda = [&](int p) {229    y = p;230  };231 232  std::call_once(flag, lambda, x);233#ifndef EMULATE_LIBCXX03234  clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}235#endif236}237 238void test_multiparam_passing_lambda() {239  std::once_flag flag;240  int x = 120;241 242  std::call_once(flag, [&](int a, int b, int c) {243    x = a + b + c;244  },245                 1, 2, 3);246 247#ifndef EMULATE_LIBCXX03248  clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}249  clang_analyzer_eval(x == 6); // expected-warning{{TRUE}}250#endif251}252 253static int global2 = 0;254void test_param_passing_lambda_global() {255  std::once_flag flag;256  global2 = 0;257  std::call_once(flag, [&](int a, int b, int c) {258    global2 = a + b + c;259  },260                 1, 2, 3);261#ifndef EMULATE_LIBCXX03262  clang_analyzer_eval(global2 == 6); // expected-warning{{TRUE}}263#endif264}265 266static int global3 = 0;267void funcptr(int a, int b, int c) {268  global3 = a + b + c;269}270 271void test_param_passing_funcptr() {272  std::once_flag flag;273  global3 = 0;274 275  std::call_once(flag, &funcptr, 1, 2, 3);276 277#ifndef EMULATE_LIBCXX03278  clang_analyzer_eval(global3 == 6); // expected-warning{{TRUE}}279#endif280}281 282void test_blocks() {283  global3 = 0;284  std::once_flag flag;285  std::call_once(flag, ^{286    global3 = 120;287  });288#ifndef EMULATE_LIBCXX03289  clang_analyzer_eval(global3 == 120); // expected-warning{{TRUE}}290#endif291}292 293int call_once() {294  return 5;295}296 297void test_non_std_call_once() {298  int x = call_once();299#ifndef EMULATE_LIBCXX03300  clang_analyzer_eval(x == 5); // expected-warning{{TRUE}}301#endif302}303 304namespace std {305template <typename d, typename e>306void call_once(d, e);307}308void g();309void test_no_segfault_on_different_impl() {310#ifndef EMULATE_LIBCXX03311  std::call_once(g, false); // no-warning312#endif313}314 315void test_lambda_refcapture() {316  static std::once_flag flag;317  int a = 6;318  std::call_once(flag, [&](int &a) { a = 42; }, a);319#ifndef EMULATE_LIBCXX03320  clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}321#endif322}323 324void test_lambda_refcapture2() {325  static std::once_flag flag;326  int a = 6;327  std::call_once(flag, [=](int &a) { a = 42; }, a);328#ifndef EMULATE_LIBCXX03329  clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}330#endif331}332 333void test_lambda_fail_refcapture() {334  static std::once_flag flag;335  int a = 6;336  std::call_once(flag, [=](int a) { a = 42; }, a);337#ifndef EMULATE_LIBCXX03338  clang_analyzer_eval(a == 42); // expected-warning{{FALSE}}339#endif340}341 342void mutator(int &param) {343  param = 42;344}345void test_reftypes_funcptr() {346  static std::once_flag flag;347  int a = 6;348  std::call_once(flag, &mutator, a);349#ifndef EMULATE_LIBCXX03350  clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}351#endif352}353 354void fail_mutator(int param) {355  param = 42;356}357void test_mutator_noref() {358  static std::once_flag flag;359  int a = 6;360  std::call_once(flag, &fail_mutator, a);361#ifndef EMULATE_LIBCXX03362  clang_analyzer_eval(a == 42); // expected-warning{{FALSE}}363#endif364}365 366// Function is implicitly treated as a function pointer367// even when an ampersand is not explicitly set.368void callbackn(int &param) {369  param = 42;370}371void test_implicit_funcptr() {372  int x = 0;373  static std::once_flag flagn;374 375  std::call_once(flagn, callbackn, x);376#ifndef EMULATE_LIBCXX03377  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}378#endif379}380 381int param_passed(int *x) {382  return *x; // no-warning, as std::function is not working yet.383}384 385void callback_taking_func_ok(std::function<void(int*)> &innerCallback) {386  innerCallback(nullptr);387}388 389// The provided callback expects an std::function, but instead a pointer390// to a C++ function is provided.391void callback_with_implicit_cast_ok() {392  std::once_flag flag;393  call_once(flag, callback_taking_func_ok, &param_passed);394}395 396void callback_taking_func(std::function<void()> &innerCallback) {397  innerCallback();398}399 400// The provided callback expects an std::function, but instead a C function401// name is provided, and C++ implicitly auto-constructs a pointer from it.402void callback_with_implicit_cast() {403  std::once_flag flag;404  call_once(flag, callback_taking_func, callback_with_implicit_cast);405}406 407std::once_flag another_once_flag;408typedef void (*my_callback_t)(int *);409my_callback_t callback;410int global_int;411 412void rdar40270582() {413  call_once(another_once_flag, callback, &global_int);414}415