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
4bool badButIgnoredFunc(int a, int b) { return a * b > 0; }
5
6class MyClass {
7public:
8 bool badFunc(int a, int b) { return a * b > 0; }
9 bool badButIgnoredFunc(int a, int b) { return a * b > 0; }
10 bool goodFunc(int a, int b) const { return a * b > 0; }
11
12 MyClass &operator=(const MyClass &rhs) { return *this; }
13
14 int operator-() { return 1; }
15
16 operator bool() const { return true; }
17
18 void operator delete(void *p) {}
19};
20
21class SomeoneElseClass {
22public:
23 bool badButIgnoredFunc(int a, int b) { return a * b > 0; }
24};
25
26bool freeFunction() {
27 return true;
28}
29
30int 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
112namespace parameter_anaylysis {
113
114struct S {
115 bool value(int) const;
116 bool leftValueRef(int &) const;
117 bool constRef(int const &) const;
118 bool rightValueRef(int &&) const;
119};
120
121void 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

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp