xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp (revision 84842f4b3ba175d744c03d40baa8e371522615e8)
1 // RUN: %check_clang_tidy %s bugprone-assert-side-effect %t -- -config="{CheckOptions: {bugprone-assert-side-effect.CheckFunctionCalls: true, bugprone-assert-side-effect.AssertMacros: 'assert,assert2,my_assert,convoluted_assert,msvc_assert', bugprone-assert-side-effect.IgnoredFunctions: 'MyClass::badButIgnoredFunc'}}" -- -fexceptions -I %S/Inputs/assert-side-effect
2 #include <assert.h>
3 
badButIgnoredFunc(int a,int b)4 bool badButIgnoredFunc(int a, int b) { return a * b > 0; }
5 
6 class MyClass {
7 public:
badFunc(int a,int b)8   bool badFunc(int a, int b) { return a * b > 0; }
badButIgnoredFunc(int a,int b)9   bool badButIgnoredFunc(int a, int b) { return a * b > 0; }
goodFunc(int a,int b) const10   bool goodFunc(int a, int b) const { return a * b > 0; }
11 
operator =(const MyClass & rhs)12   MyClass &operator=(const MyClass &rhs) { return *this; }
13 
operator -()14   int operator-() { return 1; }
15 
operator bool() const16   operator bool() const { return true; }
17 
operator delete(void * p)18   void operator delete(void *p) {}
19 };
20 
21 class SomeoneElseClass {
22 public:
badButIgnoredFunc(int a,int b)23   bool badButIgnoredFunc(int a, int b) { return a * b > 0; }
24 };
25 
freeFunction()26 bool freeFunction() {
27   return true;
28 }
29 
main()30 int main() {
31 
32   int X = 0;
33   bool B = false;
34   assert(X == 1);
35 
36   assert(X = 1);
37   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds [bugprone-assert-side-effect]
38   my_assert(X = 1);
39   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in my_assert() condition discarded in release builds
40   convoluted_assert(X = 1);
41   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in convoluted_assert() condition discarded in release builds
42   not_my_assert(X = 1);
43 
44   assert(++X);
45   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
46   assert(!B);
47 
48   assert(B || true);
49 
50   assert(freeFunction());
51   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
52 
53   MyClass mc;
54   SomeoneElseClass sec;
55   assert(mc.badFunc(0, 1));
56   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
57   assert(mc.badButIgnoredFunc(0, 1));
58   // badButIgnoredFunc is not ignored as only class members are ignored by the config
59   assert(badButIgnoredFunc(0, 1));
60   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
61   // sec.badButIgnoredFunc is not ignored as only MyClass members are ignored by the config
62   assert(sec.badButIgnoredFunc(0, 1));
63   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
64   assert(mc.goodFunc(0, 1));
65 
66   MyClass mc2;
67   assert(mc2 = mc);
68   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
69 
70   assert(-mc > 0);
71 
72   MyClass *mcp;
73   assert(mcp = new MyClass);
74   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
75 
76   assert((delete mcp, false));
77   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
78 
79   assert((throw 1, false));
80   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
81 
82   assert2(1 == 2 - 1);
83 
84   msvc_assert(mc2 = mc);
85   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in msvc_assert() condition discarded in release builds
86 
87   struct OperatorTest {
88     int operator<<(int i) const { return i; }
89     int operator<<(int i) { return i; }
90     int operator+=(int i) const { return i; }
91     int operator+=(int i) { return i; }
92   };
93 
94   const OperatorTest const_instance;
95   assert(const_instance << 1);
96   assert(const_instance += 1);
97 
98   OperatorTest non_const_instance;
99   assert(static_cast<const OperatorTest>(non_const_instance) << 1);
100   assert(static_cast<const OperatorTest>(non_const_instance) += 1);
101   assert(non_const_instance << 1);
102   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
103   assert(non_const_instance += 1);
104   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
105 
106   assert(5<<1);
107   assert(5>>1);
108 
109   return 0;
110 }
111 
112 namespace parameter_anaylysis {
113 
114 struct S {
115   bool value(int) const;
116   bool leftValueRef(int &) const;
117   bool constRef(int const &) const;
118   bool rightValueRef(int &&) const;
119 };
120 
foo()121 void foo() {
122   S s{};
123   int i = 0;
124   assert(s.value(0));
125   assert(s.value(i));
126   assert(s.leftValueRef(i));
127   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
128   assert(s.constRef(0));
129   assert(s.constRef(i));
130   assert(s.rightValueRef(0));
131   assert(s.rightValueRef(static_cast<int &&>(i)));
132 }
133 
134 } // namespace parameter_anaylysis
135