1 // RUN: %check_clang_tidy %s bugprone-assert-side-effect %t -- -config="{CheckOptions: [{key: bugprone-assert-side-effect.CheckFunctionCalls, value: true}, {key: bugprone-assert-side-effect.AssertMacros, value: 'assert,assert2,my_assert,convoluted_assert,msvc_assert'}]}" -- -fexceptions
2 
3 //===--- assert definition block ------------------------------------------===//
abort()4 int abort() { return 0; }
5 
6 #ifdef NDEBUG
7 #define assert(x) 1
8 #else
9 #define assert(x)                                                              \
10   if (!(x))                                                                    \
11   (void)abort()
12 #endif
13 
14 void print(...);
15 #define assert2(e) (__builtin_expect(!(e), 0) ?                                \
16                        print (#e, __FILE__, __LINE__) : (void)0)
17 
18 #ifdef NDEBUG
19 #define my_assert(x) 1
20 #else
21 #define my_assert(x)                                                           \
22   ((void)((x) ? 1 : abort()))
23 #endif
24 
25 #ifdef NDEBUG
26 #define not_my_assert(x) 1
27 #else
28 #define not_my_assert(x)                                                       \
29   if (!(x))                                                                    \
30   (void)abort()
31 #endif
32 
33 #define real_assert(x) ((void)((x) ? 1 : abort()))
34 #define wrap1(x) real_assert(x)
35 #define wrap2(x) wrap1(x)
36 #define convoluted_assert(x) wrap2(x)
37 
38 #define msvc_assert(expression) (void)(                                        \
39             (!!(expression)) ||                                                \
40             (abort(), 0)                                                       \
41         )
42 
43 
44 //===----------------------------------------------------------------------===//
45 
46 class MyClass {
47 public:
badFunc(int a,int b)48   bool badFunc(int a, int b) { return a * b > 0; }
goodFunc(int a,int b) const49   bool goodFunc(int a, int b) const { return a * b > 0; }
50 
operator =(const MyClass & rhs)51   MyClass &operator=(const MyClass &rhs) { return *this; }
52 
operator -()53   int operator-() { return 1; }
54 
operator bool() const55   operator bool() const { return true; }
56 
operator delete(void * p)57   void operator delete(void *p) {}
58 };
59 
freeFunction()60 bool freeFunction() {
61   return true;
62 }
63 
main()64 int main() {
65 
66   int X = 0;
67   bool B = false;
68   assert(X == 1);
69 
70   assert(X = 1);
71   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds [bugprone-assert-side-effect]
72   my_assert(X = 1);
73   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in my_assert() condition discarded in release builds
74   convoluted_assert(X = 1);
75   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in convoluted_assert() condition discarded in release builds
76   not_my_assert(X = 1);
77 
78   assert(++X);
79   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
80   assert(!B);
81 
82   assert(B || true);
83 
84   assert(freeFunction());
85   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
86 
87   MyClass mc;
88   assert(mc.badFunc(0, 1));
89   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
90   assert(mc.goodFunc(0, 1));
91 
92   MyClass mc2;
93   assert(mc2 = mc);
94   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
95 
96   assert(-mc > 0);
97 
98   MyClass *mcp;
99   assert(mcp = new MyClass);
100   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
101 
102   assert((delete mcp, false));
103   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
104 
105   assert((throw 1, false));
106   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
107 
108   assert2(1 == 2 - 1);
109 
110   msvc_assert(mc2 = mc);
111   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in msvc_assert() condition discarded in release builds
112 
113   return 0;
114 }
115