brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · 995d872 Raw
126 lines · c
1// RUN: %check_clang_tidy %s bugprone-macro-repeated-side-effects %t2 3#define badA(x,y)  ((x)+((x)+(y))+(y))4void bad(int ret, int a, int b) {5  ret = badA(a++, b);6  // CHECK-NOTES: :[[@LINE-1]]:14: warning: side effects in the 1st macro argument 'x' are repeated in macro expansion [bugprone-macro-repeated-side-effects]7  // CHECK-NOTES: :[[@LINE-4]]:9: note: macro 'badA' defined here8  ret = badA(++a, b);9  // CHECK-NOTES: :[[@LINE-1]]:14: warning: side effects in the 1st macro argument 'x'10  // CHECK-NOTES: :[[@LINE-7]]:9: note: macro 'badA' defined here11  ret = badA(a--, b);12  // CHECK-NOTES: :[[@LINE-1]]:14: warning: side effects in the 1st macro argument 'x'13  // CHECK-NOTES: :[[@LINE-10]]:9: note: macro 'badA' defined here14  ret = badA(--a, b);15  // CHECK-NOTES: :[[@LINE-1]]:14: warning: side effects in the 1st macro argument 'x'16  // CHECK-NOTES: :[[@LINE-13]]:9: note: macro 'badA' defined here17  ret = badA(a, b++);18  // CHECK-NOTES: :[[@LINE-1]]:17: warning: side effects in the 2nd macro argument 'y'19  // CHECK-NOTES: :[[@LINE-16]]:9: note: macro 'badA' defined here20  ret = badA(a, ++b);21  // CHECK-NOTES: :[[@LINE-1]]:17: warning: side effects in the 2nd macro argument 'y'22  // CHECK-NOTES: :[[@LINE-19]]:9: note: macro 'badA' defined here23  ret = badA(a, b--);24  // CHECK-NOTES: :[[@LINE-1]]:17: warning: side effects in the 2nd macro argument 'y'25  // CHECK-NOTES: :[[@LINE-22]]:9: note: macro 'badA' defined here26  ret = badA(a, --b);27  // CHECK-NOTES: :[[@LINE-1]]:17: warning: side effects in the 2nd macro argument 'y'28  // CHECK-NOTES: :[[@LINE-25]]:9: note: macro 'badA' defined here29}30 31 32#define MIN(A,B)     ((A) < (B) ? (A) : (B))                        // single ?:33#define LIMIT(X,A,B) ((X) < (A) ? (A) : ((X) > (B) ? (B) : (X)))    // two ?:34void question(int x) {35  MIN(x++, 12);36  // CHECK-NOTES: :[[@LINE-1]]:7: warning: side effects in the 1st macro argument 'A'37  // CHECK-NOTES: :[[@LINE-5]]:9: note: macro 'MIN' defined here38  MIN(34, x++);39  // CHECK-NOTES: :[[@LINE-1]]:11: warning: side effects in the 2nd macro argument 'B'40  // CHECK-NOTES: :[[@LINE-8]]:9: note: macro 'MIN' defined here41  LIMIT(x++, 0, 100);42  // CHECK-NOTES: :[[@LINE-1]]:9: warning: side effects in the 1st macro argument 'X'43  // CHECK-NOTES: :[[@LINE-10]]:9: note: macro 'LIMIT' defined here44  LIMIT(20, x++, 100);45  // CHECK-NOTES: :[[@LINE-1]]:13: warning: side effects in the 2nd macro argument 'A'46  // CHECK-NOTES: :[[@LINE-13]]:9: note: macro 'LIMIT' defined here47  LIMIT(20, 0, x++);48  // CHECK-NOTES: :[[@LINE-1]]:16: warning: side effects in the 3rd macro argument 'B'49  // CHECK-NOTES: :[[@LINE-16]]:9: note: macro 'LIMIT' defined here50}51 52// False positive: Repeated side effects is intentional.53// It is hard to know when it's done by intention so right now we warn.54#define UNROLL(A)    {A A}55void fp1(int i) {56  UNROLL({ i++; });57  // CHECK-NOTES: :[[@LINE-1]]:10: warning: side effects in the 1st macro argument 'A'58  // CHECK-NOTES: :[[@LINE-4]]:9: note: macro 'UNROLL' defined here59}60 61// Do not produce a false positive on a strchr() macro. Explanation; Currently the '?'62// triggers the test to bail out, because it cannot evaluate __builtin_constant_p(c).63#  define strchrs(s, c) \64  (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s)	      \65		  && (c) == '\0'					      \66		  ? (char *) __rawmemchr (s, c)				      \67		  : __builtin_strchr (s, c)))68char* __rawmemchr(char* a, char b) {69  return a;70}71void pass(char* pstr, char ch) {72  strchrs(pstr, ch++); // No error.73}74 75// Check large arguments (t=20, u=21).76#define largeA(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, x, y, z) \77  ((a) + (a) + (b) + (b) + (c) + (c) + (d) + (d) + (e) + (e) + (f) + (f) + (g) + (g) +    \78   (h) + (h) + (i) + (i) + (j) + (j) + (k) + (k) + (l) + (l) + (m) + (m) + (n) + (n) +    \79   (o) + (o) + (p) + (p) + (q) + (q) + (r) + (r) + (s) + (s) + (t) + (t) + (u) + (u) +    \80   (v) + (v) + (x) + (x) + (y) + (y) + (z) + (z))81void large(int a) {82  largeA(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a++, 0, 0, 0, 0, 0, 0);83  // CHECK-NOTES: :[[@LINE-1]]:64: warning: side effects in the 19th macro argument 's'84  // CHECK-NOTES: :[[@LINE-8]]:9: note: macro 'largeA' defined here85  largeA(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a++, 0, 0, 0, 0, 0);86  // CHECK-NOTES: :[[@LINE-1]]:67: warning: side effects in the 20th macro argument 't'87  // CHECK-NOTES: :[[@LINE-11]]:9: note: macro 'largeA' defined here88  largeA(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a++, 0, 0, 0, 0);89  // CHECK-NOTES: :[[@LINE-1]]:70: warning: side effects in the 21st macro argument 'u'90  // CHECK-NOTES: :[[@LINE-14]]:9: note: macro 'largeA' defined here91}92 93// Passing macro argument as argument to __builtin_constant_p and macros.94#define builtinbad(x)      (__builtin_constant_p(x) + (x) + (x))95#define builtingood1(x)    (__builtin_constant_p(x) + (x))96#define builtingood2(x)    ((__builtin_constant_p(x) && (x)) || (x))97#define macrobad(x)        (builtingood1(x) + (x) + (x))98#define macrogood(x)       (builtingood1(x) + (x))99void builtins(int ret, int a) {100  ret += builtinbad(a++);101  // CHECK-NOTES: :[[@LINE-1]]:21: warning: side effects in the 1st macro argument 'x'102  // CHECK-NOTES: :[[@LINE-8]]:9: note: macro 'builtinbad' defined here103 104  ret += builtingood1(a++);105  ret += builtingood2(a++);106 107  ret += macrobad(a++);108  // CHECK-NOTES: :[[@LINE-1]]:19: warning: side effects in the 1st macro argument 'x'109  // CHECK-NOTES: :[[@LINE-12]]:9: note: macro 'macrobad' defined here110 111  ret += macrogood(a++);112}113 114// Bail out for conditionals.115#define condB(x,y)  if(x) {x=y;} else {x=y + 1;}116void conditionals(int a, int b)117{118  condB(a, b++);119}120 121void log(const char *s, int v);122#define LOG(val) log(#val, (val))123void test_log(int a) {124  LOG(a++);125}126