Advertisement
Guest User

Untitled

a guest
May 27th, 2015
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.68 KB | None | 0 0
  1. diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
  2. index acc9a20..f221d80 100644
  3. --- gcc/c-family/c-common.c
  4. +++ gcc/c-family/c-common.c
  5. @@ -11612,6 +11612,53 @@ maybe_warn_unused_local_typedefs (void)
  6. vec_free (l->local_typedefs);
  7. }
  8.  
  9. +/* Warn about boolean expression compared with an integer value different
  10. + from true/false. Warns also e.g. about "(i1 == i2) == 2".
  11. + LOC is the location of the comparison, CODE is its code, OP0 and OP1
  12. + are the operands of the comparison. The caller must ensure that
  13. + either operand is a boolean expression. */
  14. +
  15. +void
  16. +maybe_warn_bool_compare (location_t loc, enum tree_code code, tree op0,
  17. + tree op1)
  18. +{
  19. + if (TREE_CODE_CLASS (code) != tcc_comparison)
  20. + return;
  21. +
  22. + /* <boolean> CMP <cst> */
  23. + if (TREE_CODE (op1) == INTEGER_CST
  24. + && !integer_zerop (op1)
  25. + && !integer_onep (op1))
  26. + {
  27. + if (code == EQ_EXPR
  28. + || ((code == GT_EXPR || code == GE_EXPR)
  29. + && tree_int_cst_sgn (op1) == 1)
  30. + || ((code == LT_EXPR || code == LE_EXPR)
  31. + && tree_int_cst_sgn (op1) == -1))
  32. + warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE "
  33. + "with boolean expression is always false", op1);
  34. + else
  35. + warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE "
  36. + "with boolean expression is always true", op1);
  37. + }
  38. + /* <cst> CMP <boolean> */
  39. + else if (TREE_CODE (op0) == INTEGER_CST
  40. + && !integer_zerop (op0)
  41. + && !integer_onep (op0))
  42. + {
  43. + if (code == EQ_EXPR
  44. + || ((code == GT_EXPR || code == GE_EXPR)
  45. + && tree_int_cst_sgn (op0) == -1)
  46. + || ((code == LT_EXPR || code == LE_EXPR)
  47. + && tree_int_cst_sgn (op0) == 1))
  48. + warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE "
  49. + "with boolean expression is always false", op0);
  50. + else
  51. + warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE "
  52. + "with boolean expression is always true", op0);
  53. + }
  54. +}
  55. +
  56. /* The C and C++ parsers both use vectors to hold function arguments.
  57. For efficiency, we keep a cache of unused vectors. This is the
  58. cache. */
  59. diff --git gcc/c-family/c-common.h gcc/c-family/c-common.h
  60. index 26aaee2..995bc8c 100644
  61. --- gcc/c-family/c-common.h
  62. +++ gcc/c-family/c-common.h
  63. @@ -1015,6 +1015,7 @@ extern void record_types_used_by_current_var_decl (tree);
  64. extern void record_locally_defined_typedef (tree);
  65. extern void maybe_record_typedef_use (tree);
  66. extern void maybe_warn_unused_local_typedefs (void);
  67. +extern void maybe_warn_bool_compare (location_t, enum tree_code, tree, tree);
  68. extern vec<tree, va_gc> *make_tree_vector (void);
  69. extern void release_tree_vector (vec<tree, va_gc> *);
  70. extern vec<tree, va_gc> *make_tree_vector_single (tree);
  71. diff --git gcc/c-family/c.opt gcc/c-family/c.opt
  72. index 356a79f..5a529b6 100644
  73. --- gcc/c-family/c.opt
  74. +++ gcc/c-family/c.opt
  75. @@ -287,6 +287,10 @@ Wbad-function-cast
  76. C ObjC Var(warn_bad_function_cast) Warning
  77. Warn about casting functions to incompatible types
  78.  
  79. +Wbool-compare
  80. +C ObjC C++ ObjC++ Var(warn_bool_compare) Warning
  81. +Warn about boolean expression compared with an integer value different from true/false
  82. +
  83. Wbuiltin-macro-redefined
  84. C ObjC C++ ObjC++ Warning
  85. Warn when a built-in preprocessor macro is undefined or redefined
  86. diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
  87. index 0ed92c6..8241b09 100644
  88. --- gcc/c/c-typeck.c
  89. +++ gcc/c/c-typeck.c
  90. @@ -10673,6 +10673,11 @@ build_binary_op (location_t location, enum tree_code code,
  91. result_type = type1;
  92. pedwarn (location, 0, "comparison between pointer and integer");
  93. }
  94. + if ((TREE_CODE (TREE_TYPE (orig_op0)) == BOOLEAN_TYPE
  95. + || truth_value_p (TREE_CODE (orig_op0)))
  96. + ^ (TREE_CODE (TREE_TYPE (orig_op1)) == BOOLEAN_TYPE
  97. + || truth_value_p (TREE_CODE (orig_op1))))
  98. + maybe_warn_bool_compare (location, code, orig_op0, orig_op1);
  99. break;
  100.  
  101. case LE_EXPR:
  102. @@ -10777,6 +10782,11 @@ build_binary_op (location_t location, enum tree_code code,
  103. result_type = type1;
  104. pedwarn (location, 0, "comparison between pointer and integer");
  105. }G
  106. + if ((TREE_CODE (TREE_TYPE (orig_op0)) == BOOLEAN_TYPE
  107. + || truth_value_p (TREE_CODE (orig_op0)))
  108. + ^ (TREE_CODE (TREE_TYPE (orig_op1)) == BOOLEAN_TYPE
  109. + || truth_value_p (TREE_CODE (orig_op1))))
  110. + maybe_warn_bool_compare (location, code, orig_op0, orig_op1);
  111. break;
  112.  
  113. default:
  114. diff --git gcc/cp/call.c gcc/cp/call.c
  115. index 7044e14..161235b 100644
  116. --- gcc/cp/call.c
  117. +++ gcc/cp/call.c
  118. @@ -5318,7 +5318,17 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
  119. /* These are saved for the sake of warn_logical_operator. */
  120. code_orig_arg1 = TREE_CODE (arg1);
  121. code_orig_arg2 = TREE_CODE (arg2);
  122. -
  123. + break;
  124. + case GT_EXPR:
  125. + case LT_EXPR:
  126. + case GE_EXPR:
  127. + case LE_EXPR:
  128. + case EQ_EXPR:
  129. + case NE_EXPR:
  130. + /* These are saved for the sake of maybe_warn_bool_compare. */
  131. + code_orig_arg1 = TREE_CODE (TREE_TYPE (arg1));
  132. + code_orig_arg2 = TREE_CODE (TREE_TYPE (arg2));
  133. + break;
  134. default:
  135. break;
  136. }
  137. @@ -5625,16 +5635,20 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
  138. warn_logical_operator (loc, code, boolean_type_node,
  139. code_orig_arg1, arg1, code_orig_arg2, arg2);
  140. /* Fall through. */
  141. - case PLUS_EXPR:
  142. - case MINUS_EXPR:
  143. - case MULT_EXPR:
  144. - case TRUNC_DIV_EXPR:
  145. case GT_EXPR:
  146. case LT_EXPR:
  147. case GE_EXPR:
  148. case LE_EXPR:
  149. case EQ_EXPR:
  150. case NE_EXPR:
  151. + if ((code_orig_arg1 == BOOLEAN_TYPE)
  152. + ^ (code_orig_arg2 == BOOLEAN_TYPE))
  153. + maybe_warn_bool_compare (loc, code, arg1, arg2);
  154. + /* Fall through. */
  155. + case PLUS_EXPR:
  156. + case MINUS_EXPR:
  157. + case MULT_EXPR:
  158. + case TRUNC_DIV_EXPR:
  159. case MAX_EXPR:
  160. case MIN_EXPR:
  161. case LSHIFT_EXPR:
  162. diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi
  163. index 6374261..bafd606 100644
  164. --- gcc/doc/invoke.texi
  165. +++ gcc/doc/invoke.texi
  166. @@ -240,6 +240,7 @@ Objective-C and Objective-C++ Dialects}.
  167. -pedantic-errors @gol
  168. -w -Wextra -Wall -Waddress -Waggregate-return @gol
  169. -Waggressive-loop-optimizations -Warray-bounds @gol
  170. +-Wbool-compare @gol
  171. -Wno-attributes -Wno-builtin-macro-redefined @gol
  172. -Wc90-c99-compat @gol
  173. -Wc++-compat -Wc++11-compat -Wcast-align -Wcast-qual @gol
  174. @@ -4221,6 +4222,18 @@ This option is only active when @option{-ftree-vrp} is active
  175. (default for @option{-O2} and above). It warns about subscripts to arrays
  176. that are always out of bounds. This warning is enabled by @option{-Wall}.
  177.  
  178. +@item -Wbool-compare
  179. +@opindex Wno-bool-compare
  180. +@opindex Wbool-compare
  181. +Warn about boolean expression compared with an integer value different from
  182. +@code{true}/@code{false}. For instance, the following comparison is
  183. +always false:
  184. +@smallexample
  185. +int n = 5;
  186. +@dots{}
  187. +if ((n > 1) == 2) @{ @dots{} @}
  188. +@end smallexample
  189. +
  190. @item -Wno-discarded-qualifiers @r{(C and Objective-C only)}
  191. @opindex Wno-discarded-qualifiers
  192. @opindex Wdiscarded-qualifiers
  193. diff --git gcc/testsuite/c-c++-common/Wbool-compare-1.c gcc/testsuite/c-c++-common/Wbool-compare-1.c
  194. index e69de29..52adcea 100644
  195. --- gcc/testsuite/c-c++-common/Wbool-compare-1.c
  196. +++ gcc/testsuite/c-c++-common/Wbool-compare-1.c
  197. @@ -0,0 +1,128 @@
  198. +/* PR c++/62153 */
  199. +/* { dg-do compile } */
  200. +/* { dg-options "-Wbool-compare" } */
  201. +
  202. +#ifndef __cplusplus
  203. +# define bool _Bool
  204. +# define true 1
  205. +# define false 0
  206. +#endif
  207. +
  208. +extern bool foo (void);
  209. +bool r;
  210. +
  211. +enum { E = 4 };
  212. +
  213. +void
  214. +fn1 (bool b)
  215. +{
  216. + r = b == 2; /* { dg-warning "with boolean expression is always false" } */
  217. + r = b != 2; /* { dg-warning "with boolean expression is always true" } */
  218. + r = b < 2; /* { dg-warning "with boolean expression is always true" } */
  219. + r = b > 2; /* { dg-warning "with boolean expression is always false" } */
  220. + r = b <= 2; /* { dg-warning "with boolean expression is always true" } */
  221. + r = b >= 2; /* { dg-warning "with boolean expression is always false" } */
  222. +
  223. + r = b == -1; /* { dg-warning "with boolean expression is always false" } */
  224. + r = b != -1; /* { dg-warning "with boolean expression is always true" } */
  225. + r = b < -1; /* { dg-warning "with boolean expression is always false" } */
  226. + r = b > -1; /* { dg-warning "with boolean expression is always true" } */
  227. + r = b <= -1; /* { dg-warning "with boolean expression is always false" } */
  228. + r = b >= -1; /* { dg-warning "with boolean expression is always true" } */
  229. +
  230. + r = foo () == 2; /* { dg-warning "with boolean expression is always false" } */
  231. + r = foo () != 2; /* { dg-warning "with boolean expression is always true" } */
  232. + r = foo () < 2; /* { dg-warning "with boolean expression is always true" } */
  233. + r = foo () > 2; /* { dg-warning "with boolean expression is always false" } */
  234. + r = foo () <= 2; /* { dg-warning "with boolean expression is always true" } */
  235. + r = foo () >= 2; /* { dg-warning "with boolean expression is always false" } */
  236. +
  237. + r = b == E; /* { dg-warning "with boolean expression is always false" } */
  238. + r = b != E; /* { dg-warning "with boolean expression is always true" } */
  239. + r = b < E; /* { dg-warning "with boolean expression is always true" } */
  240. + r = b > E; /* { dg-warning "with boolean expression is always false" } */
  241. + r = b <= E; /* { dg-warning "with boolean expression is always true" } */
  242. + r = b >= E; /* { dg-warning "with boolean expression is always false" } */
  243. +
  244. + /* Swap LHS and RHS. */
  245. + r = 2 == b; /* { dg-warning "with boolean expression is always false" } */
  246. + r = 2 != b; /* { dg-warning "with boolean expression is always true" } */
  247. + r = 2 < b; /* { dg-warning "with boolean expression is always false" } */
  248. + r = 2 > b; /* { dg-warning "with boolean expression is always true" } */
  249. + r = 2 <= b; /* { dg-warning "with boolean expression is always false" } */
  250. + r = 2 >= b; /* { dg-warning "with boolean expression is always true" } */
  251. +
  252. + r = -1 == b; /* { dg-warning "with boolean expression is always false" } */
  253. + r = -1 != b; /* { dg-warning "with boolean expression is always true" } */
  254. + r = -1 < b; /* { dg-warning "with boolean expression is always true" } */
  255. + r = -1 > b; /* { dg-warning "with boolean expression is always false" } */
  256. + r = -1 <= b; /* { dg-warning "with boolean expression is always true" } */
  257. + r = -1 >= b; /* { dg-warning "with boolean expression is always false" } */
  258. +
  259. + r = E == b; /* { dg-warning "with boolean expression is always false" } */
  260. + r = E != b; /* { dg-warning "with boolean expression is always true" } */
  261. + r = E < b; /* { dg-warning "with boolean expression is always false" } */
  262. + r = E > b; /* { dg-warning "with boolean expression is always true" } */
  263. + r = E <= b; /* { dg-warning "with boolean expression is always false" } */
  264. + r = E >= b; /* { dg-warning "with boolean expression is always true" } */
  265. +
  266. + /* These are of course fine. */
  267. + r = b == false;
  268. + r = b != false;
  269. + r = b == true;
  270. + r = b != true;
  271. +
  272. + /* Some of these don't make much sense, but we don't warn. */
  273. + r = b < false;
  274. + r = b >= false;
  275. + r = b <= false;
  276. + r = b > false;
  277. + r = b < true;
  278. + r = b >= true;
  279. + r = b <= true;
  280. + r = b > true;
  281. +}
  282. +
  283. +void
  284. +fn2 (int i1, int i2)
  285. +{
  286. + r = (i1 == i2) == 2; /* { dg-warning "with boolean expression is always false" } */
  287. + r = (i1 == i2) != 2; /* { dg-warning "with boolean expression is always true" } */
  288. + r = (i1 == i2) < 2; /* { dg-warning "with boolean expression is always true" } */
  289. + r = (i1 == i2) > 2; /* { dg-warning "with boolean expression is always false" } */
  290. + r = (i1 == i2) <= 2; /* { dg-warning "with boolean expression is always true" } */
  291. + r = (i1 == i2) >= 2; /* { dg-warning "with boolean expression is always false" } */
  292. +
  293. + r = (i1 == i2) == -1; /* { dg-warning "with boolean expression is always false" } */
  294. + r = (i1 == i2) != -1; /* { dg-warning "with boolean expression is always true" } */
  295. + r = (i1 == i2) < -1; /* { dg-warning "with boolean expression is always false" } */
  296. + r = (i1 == i2) > -1; /* { dg-warning "with boolean expression is always true" } */
  297. + r = (i1 == i2) <= -1; /* { dg-warning "with boolean expression is always false" } */
  298. + r = (i1 == i2) >= -1; /* { dg-warning "with boolean expression is always true" } */
  299. +
  300. + r = (i1 == i2) == E; /* { dg-warning "with boolean expression is always false" } */
  301. + r = (i1 == i2) != E; /* { dg-warning "with boolean expression is always true" } */
  302. + r = (i1 == i2) < E; /* { dg-warning "with boolean expression is always true" } */
  303. + r = (i1 == i2) > E; /* { dg-warning "with boolean expression is always false" } */
  304. + r = (i1 == i2) <= E; /* { dg-warning "with boolean expression is always true" } */
  305. + r = (i1 == i2) >= E; /* { dg-warning "with boolean expression is always false" } */
  306. +}
  307. +
  308. +void
  309. +fn3 (int n, bool b)
  310. +{
  311. + /* Don't warn here. */
  312. + r = b == n;
  313. + r = b != n;
  314. + r = b < n;
  315. + r = b > n;
  316. + r = b <= n;
  317. + r = b >= n;
  318. +
  319. + r = n == E;
  320. + r = n != E;
  321. + r = n < E;
  322. + r = n > E;
  323. + r = n <= E;
  324. + r = n >= E;
  325. +}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement