xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp (revision d4a4585165f5c6ca8c42920b70e1b47696ff1172)
1 // RUN: %check_clang_tidy %s bugprone-inc-dec-in-conditions %t
2 
3 template<typename T>
4 struct 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 
14 template<typename T>
15 struct Container {
16   Iterator<T> begin();
17   Iterator<T> end();
18 };
19 
f(int x)20 bool 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 
f2(int x)25 bool 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 
c(Container<int> x)30 bool 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 
c2(Container<int> x)36 bool 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 
d(int x)42 bool 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 
d2(int x)47 bool 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 
g(Container<int> x)52 bool 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 
g2(Container<int> x)58 bool 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 
doubleCheck(Container<int> x)64 bool 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 
72 namespace PR85838 {
test()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