149 lines · c
1// RUN: %check_clang_tidy %s android-comparison-in-temp-failure-retry %t2 3#define TEMP_FAILURE_RETRY(x) \4 ({ \5 __typeof__(x) __z; \6 do \7 __z = (x); \8 while (__z == -1); \9 __z; \10 })11 12int foo(void);13int bar(int a);14 15void test(void) {16 int i;17 TEMP_FAILURE_RETRY((i = foo()));18 TEMP_FAILURE_RETRY(foo());19 TEMP_FAILURE_RETRY((foo()));20 21 TEMP_FAILURE_RETRY(foo() == 1);22 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: top-level comparison in TEMP_FAILURE_RETRY [android-comparison-in-temp-failure-retry]23 TEMP_FAILURE_RETRY((foo() == 1));24 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: top-level comparison in TEMP_FAILURE_RETRY25 TEMP_FAILURE_RETRY((int)(foo() == 1));26 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY27 28 TEMP_FAILURE_RETRY(bar(foo() == 1));29 TEMP_FAILURE_RETRY((bar(foo() == 1)));30 TEMP_FAILURE_RETRY((bar(foo() == 1)) == 1);31 // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: top-level comparison in TEMP_FAILURE_RETRY32 TEMP_FAILURE_RETRY(((bar(foo() == 1)) == 1));33 // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: top-level comparison in TEMP_FAILURE_RETRY34 TEMP_FAILURE_RETRY((int)((bar(foo() == 1)) == 1));35 // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: top-level comparison in TEMP_FAILURE_RETRY36 37#define INDIRECT TEMP_FAILURE_RETRY38 INDIRECT(foo());39 INDIRECT((foo() == 1));40 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: top-level comparison in TEMP_FAILURE_RETRY41 INDIRECT(bar(foo() == 1));42 INDIRECT((int)((bar(foo() == 1)) == 1));43 // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: top-level comparison in TEMP_FAILURE_RETRY44 45#define TFR(x) TEMP_FAILURE_RETRY(x)46 TFR(foo());47 TFR((foo() == 1));48 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: top-level comparison in TEMP_FAILURE_RETRY49 TFR(bar(foo() == 1));50 TFR((int)((bar(foo() == 1)) == 1));51 // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: top-level comparison in TEMP_FAILURE_RETRY52 53#define ADD_TFR(x) (1 + TEMP_FAILURE_RETRY(x) + 1)54 ADD_TFR(foo());55 ADD_TFR(foo() == 1);56 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: top-level comparison in TEMP_FAILURE_RETRY57 58 ADD_TFR(bar(foo() == 1));59 ADD_TFR((int)((bar(foo() == 1)) == 1));60 // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: top-level comparison in TEMP_FAILURE_RETRY61 62#define ADDP_TFR(x) (1 + TEMP_FAILURE_RETRY((x)) + 1)63 ADDP_TFR(foo());64 ADDP_TFR((foo() == 1));65 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: top-level comparison in TEMP_FAILURE_RETRY66 67 ADDP_TFR(bar(foo() == 1));68 ADDP_TFR((int)((bar(foo() == 1)) == 1));69 // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: top-level comparison in TEMP_FAILURE_RETRY70 71#define MACRO TEMP_FAILURE_RETRY(foo() == 1)72 MACRO;73 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: top-level comparison in TEMP_FAILURE_RETRY74 75 // Be sure that being a macro arg doesn't mess with this.76#define ID(x) (x)77 ID(ADDP_TFR(bar(foo() == 1)));78 ID(ADDP_TFR(bar(foo() == 1) == 1));79 // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: top-level comparison in TEMP_FAILURE_RETRY80 ID(MACRO);81 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: top-level comparison in TEMP_FAILURE_RETRY82 83#define CMP(x) x == 184 TEMP_FAILURE_RETRY(CMP(foo()));85 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: top-level comparison in TEMP_FAILURE_RETRY86}87 88// Be sure that it works inside of things like loops, if statements, etc.89void control_flow(void) {90 do {91 if (TEMP_FAILURE_RETRY(foo())) {92 }93 94 if (TEMP_FAILURE_RETRY(foo() == 1)) {95 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY96 }97 98 if (TEMP_FAILURE_RETRY(bar(foo() == 1))) {99 }100 101 if (TEMP_FAILURE_RETRY(bar(foo() == 1) == 1)) {102 // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: top-level comparison in TEMP_FAILURE_RETRY103 }104 } while (TEMP_FAILURE_RETRY(foo() == 1));105 // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: top-level comparison in TEMP_FAILURE_RETRY106}107 108void with_nondependent_variable_type(void) {109#undef TEMP_FAILURE_RETRY110#define TEMP_FAILURE_RETRY(x) \111 ({ \112 long int __z; \113 do \114 __z = (x); \115 while (__z == -1); \116 __z; \117 })118 119 TEMP_FAILURE_RETRY((foo()));120 TEMP_FAILURE_RETRY((int)(foo() == 1));121 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY122 TEMP_FAILURE_RETRY((bar(foo() == 1)));123 TEMP_FAILURE_RETRY((int)((bar(foo() == 1)) == 1));124 // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: top-level comparison in TEMP_FAILURE_RETRY125}126 127// I can't find a case where TEMP_FAILURE_RETRY is implemented like this, but if128// we can cheaply support it, I don't see why not.129void obscured_temp_failure_retry(void) {130#undef TEMP_FAILURE_RETRY131#define IMPL(x) \132 ({ \133 __typeof__(x) __z; \134 do \135 __z = (x); \136 while (__z == -1); \137 __z; \138 })139 140#define IMPL2(x) IMPL(x)141#define TEMP_FAILURE_RETRY(x) IMPL2(x)142 TEMP_FAILURE_RETRY((foo()));143 TEMP_FAILURE_RETRY((int)(foo() == 1));144 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY145 TEMP_FAILURE_RETRY((bar(foo() == 1)));146 TEMP_FAILURE_RETRY((int)((bar(foo() == 1)) == 1));147 // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: top-level comparison in TEMP_FAILURE_RETRY148}149