1// RUN: %check_clang_tidy %s bugprone-inc-dec-in-conditions %t
2
3template<typename T>
4struct Iterator {
5 Iterator operator++(int);
6 Iterator operator--(int);
7 Iterator& operator++();
8 Iterator& operator--();
9 T operator*();
10 bool operator==(Iterator) const;
11 bool operator!=(Iterator) const;
12};
13
14template<typename T>
15struct Container {
16 Iterator<T> begin();
17 Iterator<T> end();
18};
19
20bool f(int x) {
21 return (++x != 5 or x == 10);
22 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: incrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
23}
24
25bool f2(int x) {
26 return (x++ != 5 or x == 10);
27 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: incrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
28}
29
30bool c(Container<int> x) {
31 auto it = x.begin();
32 return (it++ != x.end() and *it);
33 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: incrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
34}
35
36bool c2(Container<int> x) {
37 auto it = x.begin();
38 return (++it != x.end() and *it);
39 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: incrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
40}
41
42bool d(int x) {
43 return (--x != 5 or x == 10);
44 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: decrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
45}
46
47bool d2(int x) {
48 return (x-- != 5 or x == 10);
49 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: decrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
50}
51
52bool g(Container<int> x) {
53 auto it = x.begin();
54 return (it-- != x.end() and *it);
55 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: decrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
56}
57
58bool g2(Container<int> x) {
59 auto it = x.begin();
60 return (--it != x.end() and *it);
61 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: decrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
62}
63
64bool doubleCheck(Container<int> x) {
65 auto it = x.begin();
66 auto it2 = x.begin();
67 return (--it != x.end() and ++it2 != x.end()) and (*it == *it2);
68 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: decrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
69 // CHECK-MESSAGES: :[[@LINE-2]]:31: warning: incrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
70}
71
72namespace PR85838 {
73 void test()
74 {
75 auto foo = 0;
76 auto bar = 0;
77 if (++foo < static_cast<decltype(foo)>(bar)) {}
78 if (static_cast<decltype(++foo)>(bar) < foo) {}
79 }
80}
81

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp