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 | |
4 | extern void work(); |
5 | |
6 | void 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 | |
21 | class MagicVector { |
22 | public: |
23 | MagicVector(); |
24 | |
25 | using iterator = int *; |
26 | |
27 | iterator begin() const; |
28 | iterator end() const; |
29 | }; |
30 | |
31 | MagicVector get(bool fail = false) { |
32 | if (fail) |
33 | *(volatile int *)0 = 1; // expected-warning {{Dereference of null pointer}} |
34 | return MagicVector{}; |
35 | } |
36 | |
37 | void 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 | |
52 | class MagicVector2 { |
53 | public: |
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 | |
68 | MagicVector2 get2() { |
69 | return MagicVector2{}; |
70 | } |
71 | |
72 | void 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 | |
87 | void 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 | |
101 | void 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 | |