Clang Project

clang_source_code/test/Analysis/cxx-for-range.cpp
1// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core -analyzer-output=plist-multi-file -o %t.plist -verify -analyzer-config eagerly-assume=false %s
2// RUN: cat %t.plist | %diff_plist %S/Inputs/expected-plists/cxx-for-range.cpp.plist -
3
4extern void work();
5
6void testLoop() {
7  int z[] = {1,2};
8  for (int y : z) {
9    work();
10    work();
11    if (y == 2)
12      *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
13    work();
14    work();
15    (void)y;
16  }
17
18  *(volatile int *)0 = 1; // no-warning
19}
20
21class MagicVector {
22public:
23  MagicVector();
24
25  using iterator = int *;
26
27  iterator begin() const;
28  iterator end() const;
29};
30
31MagicVector get(bool fail = false) {
32  if (fail)
33    *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
34  return MagicVector{};
35}
36
37void testLoopOpaqueCollection() {
38  for (int y : get()) {
39    work();
40    work();
41    if (y == 2)
42      *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
43    work();
44    work();
45    (void)y;
46  }
47
48  *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
49}
50
51
52class MagicVector2 {
53public:
54  MagicVector2();
55
56  class iterator {
57  public:
58    int operator*() const;
59    iterator &operator++();
60    bool operator==(const iterator &);
61    bool operator!=(const iterator &);
62  };
63
64  iterator begin() const;
65  iterator end() const;
66};
67
68MagicVector2 get2() {
69  return MagicVector2{};
70}
71
72void testLoopOpaqueIterator() {
73  for (int y : get2()) {
74    work();
75    work();
76    if (y == 2)
77      *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
78    work();
79    work();
80    (void)y;
81  }
82
83  *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}}
84}
85
86
87void testLoopErrorInRange() {
88  for (int y : get(true)) { // error inside get()
89    work();
90    work();
91    if (y == 2)
92      *(volatile int *)0 = 1; // no-warning
93    work();
94    work();
95    (void)y;
96  }
97
98  *(volatile int *)0 = 1; // no-warning
99}
100
101void testForRangeInit() {
102  for (int *arr[3] = {nullptr, nullptr, nullptr}; int *p : arr) // expected-warning {{extension}}
103    *p = 1; // expected-warning {{Dereference of null pointer}}
104}
105