1e8a3ddafSNathan James // 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
20d6d8a85SCarlos Galvez #include <assert.h>
389a1d03eSRichard
badButIgnoredFunc(int a,int b)489a1d03eSRichard bool badButIgnoredFunc(int a, int b) { return a * b > 0; }
589a1d03eSRichard
689a1d03eSRichard class MyClass {
789a1d03eSRichard public:
badFunc(int a,int b)889a1d03eSRichard bool badFunc(int a, int b) { return a * b > 0; }
badButIgnoredFunc(int a,int b)989a1d03eSRichard bool badButIgnoredFunc(int a, int b) { return a * b > 0; }
goodFunc(int a,int b) const1089a1d03eSRichard bool goodFunc(int a, int b) const { return a * b > 0; }
1189a1d03eSRichard
operator =(const MyClass & rhs)1289a1d03eSRichard MyClass &operator=(const MyClass &rhs) { return *this; }
1389a1d03eSRichard
operator -()1489a1d03eSRichard int operator-() { return 1; }
1589a1d03eSRichard
operator bool() const1689a1d03eSRichard operator bool() const { return true; }
1789a1d03eSRichard
operator delete(void * p)1889a1d03eSRichard void operator delete(void *p) {}
1989a1d03eSRichard };
2089a1d03eSRichard
2189a1d03eSRichard class SomeoneElseClass {
2289a1d03eSRichard public:
badButIgnoredFunc(int a,int b)2389a1d03eSRichard bool badButIgnoredFunc(int a, int b) { return a * b > 0; }
2489a1d03eSRichard };
2589a1d03eSRichard
freeFunction()2689a1d03eSRichard bool freeFunction() {
2789a1d03eSRichard return true;
2889a1d03eSRichard }
2989a1d03eSRichard
main()3089a1d03eSRichard int main() {
3189a1d03eSRichard
3289a1d03eSRichard int X = 0;
3389a1d03eSRichard bool B = false;
3489a1d03eSRichard assert(X == 1);
3589a1d03eSRichard
3689a1d03eSRichard assert(X = 1);
3789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds [bugprone-assert-side-effect]
3889a1d03eSRichard my_assert(X = 1);
3989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in my_assert() condition discarded in release builds
4089a1d03eSRichard convoluted_assert(X = 1);
4189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in convoluted_assert() condition discarded in release builds
4289a1d03eSRichard not_my_assert(X = 1);
4389a1d03eSRichard
4489a1d03eSRichard assert(++X);
4589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
4689a1d03eSRichard assert(!B);
4789a1d03eSRichard
4889a1d03eSRichard assert(B || true);
4989a1d03eSRichard
5089a1d03eSRichard assert(freeFunction());
5189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
5289a1d03eSRichard
5389a1d03eSRichard MyClass mc;
5489a1d03eSRichard SomeoneElseClass sec;
5589a1d03eSRichard assert(mc.badFunc(0, 1));
5689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
5789a1d03eSRichard assert(mc.badButIgnoredFunc(0, 1));
5889a1d03eSRichard // badButIgnoredFunc is not ignored as only class members are ignored by the config
5989a1d03eSRichard assert(badButIgnoredFunc(0, 1));
6089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
6189a1d03eSRichard // sec.badButIgnoredFunc is not ignored as only MyClass members are ignored by the config
6289a1d03eSRichard assert(sec.badButIgnoredFunc(0, 1));
6389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
6489a1d03eSRichard assert(mc.goodFunc(0, 1));
6589a1d03eSRichard
6689a1d03eSRichard MyClass mc2;
6789a1d03eSRichard assert(mc2 = mc);
6889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
6989a1d03eSRichard
7089a1d03eSRichard assert(-mc > 0);
7189a1d03eSRichard
7289a1d03eSRichard MyClass *mcp;
7389a1d03eSRichard assert(mcp = new MyClass);
7489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
7589a1d03eSRichard
7689a1d03eSRichard assert((delete mcp, false));
7789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
7889a1d03eSRichard
7989a1d03eSRichard assert((throw 1, false));
8089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
8189a1d03eSRichard
8289a1d03eSRichard assert2(1 == 2 - 1);
8389a1d03eSRichard
8489a1d03eSRichard msvc_assert(mc2 = mc);
8589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in msvc_assert() condition discarded in release builds
8689a1d03eSRichard
87c95d5813Sschenker struct OperatorTest {
88c95d5813Sschenker int operator<<(int i) const { return i; }
89c95d5813Sschenker int operator<<(int i) { return i; }
90c95d5813Sschenker int operator+=(int i) const { return i; }
91c95d5813Sschenker int operator+=(int i) { return i; }
92c95d5813Sschenker };
93c95d5813Sschenker
94c95d5813Sschenker const OperatorTest const_instance;
95c95d5813Sschenker assert(const_instance << 1);
96c95d5813Sschenker assert(const_instance += 1);
97c95d5813Sschenker
98c95d5813Sschenker OperatorTest non_const_instance;
99c95d5813Sschenker assert(static_cast<const OperatorTest>(non_const_instance) << 1);
100c95d5813Sschenker assert(static_cast<const OperatorTest>(non_const_instance) += 1);
101c95d5813Sschenker assert(non_const_instance << 1);
102c95d5813Sschenker // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
103c95d5813Sschenker assert(non_const_instance += 1);
104c95d5813Sschenker // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
105c95d5813Sschenker
106c95d5813Sschenker assert(5<<1);
107c95d5813Sschenker assert(5>>1);
108c95d5813Sschenker
10989a1d03eSRichard return 0;
11089a1d03eSRichard }
111*84842f4bSCongcong Cai
112*84842f4bSCongcong Cai namespace parameter_anaylysis {
113*84842f4bSCongcong Cai
114*84842f4bSCongcong Cai struct S {
115*84842f4bSCongcong Cai bool value(int) const;
116*84842f4bSCongcong Cai bool leftValueRef(int &) const;
117*84842f4bSCongcong Cai bool constRef(int const &) const;
118*84842f4bSCongcong Cai bool rightValueRef(int &&) const;
119*84842f4bSCongcong Cai };
120*84842f4bSCongcong Cai
foo()121*84842f4bSCongcong Cai void foo() {
122*84842f4bSCongcong Cai S s{};
123*84842f4bSCongcong Cai int i = 0;
124*84842f4bSCongcong Cai assert(s.value(0));
125*84842f4bSCongcong Cai assert(s.value(i));
126*84842f4bSCongcong Cai assert(s.leftValueRef(i));
127*84842f4bSCongcong Cai // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
128*84842f4bSCongcong Cai assert(s.constRef(0));
129*84842f4bSCongcong Cai assert(s.constRef(i));
130*84842f4bSCongcong Cai assert(s.rightValueRef(0));
131*84842f4bSCongcong Cai assert(s.rightValueRef(static_cast<int &&>(i)));
132*84842f4bSCongcong Cai }
133*84842f4bSCongcong Cai
134*84842f4bSCongcong Cai } // namespace parameter_anaylysis
135