adlint 2.4.6 → 2.4.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (306) hide show
  1. data/ChangeLog +163 -0
  2. data/MANIFEST +12 -0
  3. data/NEWS +20 -4
  4. data/etc/conf.d/x86_64-ubuntu_12.04/cinit-gcc_4.6.3.erb +2 -2
  5. data/etc/mesg.d/c_builtin/en_US/messages.yml +1 -1
  6. data/etc/mesg.d/c_builtin/ja_JP/messages.yml +1 -1
  7. data/etc/mesg.d/core/en_US/messages.yml +1 -1
  8. data/etc/mesg.d/core/ja_JP/messages.yml +1 -1
  9. data/features/code_check/E0013.feature +0 -2
  10. data/features/code_check/W0001.feature +0 -2
  11. data/features/code_check/W0002.feature +0 -2
  12. data/features/code_check/W0003.feature +0 -2
  13. data/features/code_check/W0007.feature +0 -2
  14. data/features/code_check/W0010.feature +1 -3
  15. data/features/code_check/W0013.feature +0 -2
  16. data/features/code_check/W0016.feature +0 -2
  17. data/features/code_check/W0017.feature +0 -2
  18. data/features/code_check/W0025.feature +0 -2
  19. data/features/code_check/W0026.feature +0 -2
  20. data/features/code_check/W0070.feature +0 -2
  21. data/features/code_check/W0071.feature +0 -2
  22. data/features/code_check/W0093.feature +0 -2
  23. data/features/code_check/W0104.feature +0 -2
  24. data/features/code_check/W0109.feature +0 -2
  25. data/features/code_check/W0119.feature +0 -2
  26. data/features/code_check/W0120.feature +0 -2
  27. data/features/code_check/W0121.feature +0 -2
  28. data/features/code_check/W0122.feature +0 -2
  29. data/features/code_check/W0123.feature +0 -2
  30. data/features/code_check/W0124.feature +0 -2
  31. data/features/code_check/W0125.feature +0 -2
  32. data/features/code_check/W0126.feature +0 -2
  33. data/features/code_check/W0127.feature +0 -2
  34. data/features/code_check/W0128.feature +0 -2
  35. data/features/code_check/W0129.feature +0 -2
  36. data/features/code_check/W0130.feature +0 -2
  37. data/features/code_check/W0131.feature +0 -2
  38. data/features/code_check/W0132.feature +0 -2
  39. data/features/code_check/W0133.feature +0 -2
  40. data/features/code_check/W0134.feature +0 -2
  41. data/features/code_check/W0135.feature +0 -2
  42. data/features/code_check/W0136.feature +0 -2
  43. data/features/code_check/W0137.feature +0 -2
  44. data/features/code_check/W0138.feature +0 -2
  45. data/features/code_check/W0139.feature +0 -2
  46. data/features/code_check/W0140.feature +0 -2
  47. data/features/code_check/W0141.feature +0 -2
  48. data/features/code_check/W0142.feature +0 -2
  49. data/features/code_check/W0143.feature +0 -2
  50. data/features/code_check/W0144.feature +0 -2
  51. data/features/code_check/W0145.feature +0 -2
  52. data/features/code_check/W0146.feature +0 -2
  53. data/features/code_check/W0147.feature +0 -2
  54. data/features/code_check/W0148.feature +0 -2
  55. data/features/code_check/W0149.feature +0 -2
  56. data/features/code_check/W0150.feature +0 -2
  57. data/features/code_check/W0151.feature +0 -2
  58. data/features/code_check/W0152.feature +0 -2
  59. data/features/code_check/W0153.feature +0 -2
  60. data/features/code_check/W0154.feature +0 -2
  61. data/features/code_check/W0155.feature +0 -2
  62. data/features/code_check/W0156.feature +0 -2
  63. data/features/code_check/W0157.feature +0 -2
  64. data/features/code_check/W0158.feature +0 -2
  65. data/features/code_check/W0159.feature +0 -2
  66. data/features/code_check/W0160.feature +0 -2
  67. data/features/code_check/W0161.feature +0 -2
  68. data/features/code_check/W0162.feature +0 -2
  69. data/features/code_check/W0163.feature +0 -2
  70. data/features/code_check/W0164.feature +0 -2
  71. data/features/code_check/W0165.feature +0 -2
  72. data/features/code_check/W0166.feature +0 -2
  73. data/features/code_check/W0167.feature +0 -2
  74. data/features/code_check/W0168.feature +0 -2
  75. data/features/code_check/W0169.feature +0 -2
  76. data/features/code_check/W0170.feature +0 -2
  77. data/features/code_check/W0171.feature +0 -2
  78. data/features/code_check/W0172.feature +0 -2
  79. data/features/code_check/W0173.feature +0 -2
  80. data/features/code_check/W0174.feature +0 -2
  81. data/features/code_check/W0175.feature +0 -2
  82. data/features/code_check/W0176.feature +0 -2
  83. data/features/code_check/W0177.feature +0 -2
  84. data/features/code_check/W0178.feature +0 -2
  85. data/features/code_check/W0179.feature +0 -2
  86. data/features/code_check/W0180.feature +0 -2
  87. data/features/code_check/W0181.feature +0 -2
  88. data/features/code_check/W0182.feature +0 -2
  89. data/features/code_check/W0183.feature +0 -2
  90. data/features/code_check/W0184.feature +0 -2
  91. data/features/code_check/W0185.feature +0 -2
  92. data/features/code_check/W0186.feature +0 -2
  93. data/features/code_check/W0187.feature +0 -2
  94. data/features/code_check/W0188.feature +0 -2
  95. data/features/code_check/W0189.feature +0 -2
  96. data/features/code_check/W0190.feature +0 -2
  97. data/features/code_check/W0191.feature +0 -2
  98. data/features/code_check/W0192.feature +0 -2
  99. data/features/code_check/W0193.feature +0 -2
  100. data/features/code_check/W0194.feature +0 -2
  101. data/features/code_check/W0195.feature +0 -2
  102. data/features/code_check/W0196.feature +0 -2
  103. data/features/code_check/W0197.feature +0 -2
  104. data/features/code_check/W0198.feature +0 -2
  105. data/features/code_check/W0199.feature +0 -2
  106. data/features/code_check/W0200.feature +0 -2
  107. data/features/code_check/W0201.feature +0 -2
  108. data/features/code_check/W0202.feature +0 -2
  109. data/features/code_check/W0203.feature +0 -2
  110. data/features/code_check/W0204.feature +0 -2
  111. data/features/code_check/W0205.feature +0 -2
  112. data/features/code_check/W0206.feature +0 -2
  113. data/features/code_check/W0207.feature +0 -2
  114. data/features/code_check/W0208.feature +0 -2
  115. data/features/code_check/W0209.feature +0 -2
  116. data/features/code_check/W0210.feature +0 -2
  117. data/features/code_check/W0211.feature +0 -2
  118. data/features/code_check/W0212.feature +0 -2
  119. data/features/code_check/W0213.feature +0 -2
  120. data/features/code_check/W0214.feature +0 -2
  121. data/features/code_check/W0215.feature +0 -2
  122. data/features/code_check/W0216.feature +0 -2
  123. data/features/code_check/W0217.feature +0 -2
  124. data/features/code_check/W0218.feature +0 -2
  125. data/features/code_check/W0219.feature +0 -2
  126. data/features/code_check/W0220.feature +0 -2
  127. data/features/code_check/W0221.feature +0 -2
  128. data/features/code_check/W0222.feature +0 -2
  129. data/features/code_check/W0223.feature +0 -2
  130. data/features/code_check/W0224.feature +0 -2
  131. data/features/code_check/W0225.feature +0 -2
  132. data/features/code_check/W0226.feature +0 -2
  133. data/features/code_check/W0227.feature +0 -2
  134. data/features/code_check/W0228.feature +0 -2
  135. data/features/code_check/W0229.feature +0 -2
  136. data/features/code_check/W0230.feature +0 -2
  137. data/features/code_check/W0231.feature +0 -2
  138. data/features/code_check/W0232.feature +0 -2
  139. data/features/code_check/W0233.feature +0 -2
  140. data/features/code_check/W0234.feature +0 -2
  141. data/features/code_check/W0235.feature +0 -2
  142. data/features/code_check/W0236.feature +0 -2
  143. data/features/code_check/W0237.feature +0 -2
  144. data/features/code_check/W0238.feature +0 -2
  145. data/features/code_check/W0239.feature +0 -2
  146. data/features/code_check/W0240.feature +0 -2
  147. data/features/code_check/W0241.feature +0 -2
  148. data/features/code_check/W0242.feature +0 -2
  149. data/features/code_check/W0243.feature +0 -2
  150. data/features/code_check/W0244.feature +0 -2
  151. data/features/code_check/W0245.feature +0 -2
  152. data/features/code_check/W0246.feature +0 -2
  153. data/features/code_check/W0247.feature +0 -2
  154. data/features/code_check/W0248.feature +0 -2
  155. data/features/code_check/W0249.feature +0 -2
  156. data/features/code_check/W0250.feature +0 -2
  157. data/features/code_check/W0251.feature +0 -2
  158. data/features/code_check/W0252.feature +0 -2
  159. data/features/code_check/W0253.feature +0 -2
  160. data/features/code_check/W0254.feature +0 -2
  161. data/features/code_check/W0425.feature +0 -2
  162. data/features/code_check/W0431.feature +0 -2
  163. data/features/code_check/W0432.feature +0 -2
  164. data/features/code_check/W0477.feature +0 -2
  165. data/features/code_check/W0478.feature +0 -2
  166. data/features/code_check/W0479.feature +0 -2
  167. data/features/code_check/W0480.feature +0 -2
  168. data/features/code_check/W0481.feature +0 -2
  169. data/features/code_check/W0482.feature +0 -2
  170. data/features/code_check/W0483.feature +0 -2
  171. data/features/code_check/W0488.feature +132 -0
  172. data/features/code_check/W0489.feature +78 -0
  173. data/features/code_check/W0490.feature +83 -0
  174. data/features/code_check/W0495.feature +60 -0
  175. data/features/code_check/W0496.feature +63 -0
  176. data/features/code_check/W0497.feature +65 -0
  177. data/features/code_check/W0498.feature +120 -0
  178. data/features/code_check/W0499.feature +63 -0
  179. data/features/code_check/W0500.feature +66 -0
  180. data/features/code_check/W0501.feature +69 -0
  181. data/features/code_check/W0502.feature +64 -0
  182. data/features/code_check/W0573.feature +0 -2
  183. data/features/code_check/W0583.feature +0 -2
  184. data/features/code_check/W0606.feature +0 -2
  185. data/features/code_check/W0635.feature +0 -2
  186. data/features/code_check/W0641.feature +0 -2
  187. data/features/code_check/W0643.feature +0 -2
  188. data/features/code_check/W0644.feature +0 -2
  189. data/features/code_check/W0645.feature +0 -2
  190. data/features/code_check/W0646.feature +0 -2
  191. data/features/code_check/W0649.feature +0 -2
  192. data/features/code_check/W0650.feature +0 -2
  193. data/features/code_check/W0655.feature +43 -0
  194. data/features/code_check/W0685.feature +0 -2
  195. data/features/code_check/W0686.feature +0 -2
  196. data/features/code_check/W0687.feature +0 -2
  197. data/features/code_check/W0688.feature +0 -2
  198. data/features/code_check/W0689.feature +0 -2
  199. data/features/code_check/W0690.feature +0 -2
  200. data/features/code_check/W0691.feature +0 -2
  201. data/features/code_check/W0692.feature +0 -2
  202. data/features/code_check/W0694.feature +0 -2
  203. data/features/code_check/W0695.feature +0 -2
  204. data/features/code_check/W0697.feature +0 -2
  205. data/features/code_check/W0698.feature +0 -2
  206. data/features/code_check/W0699.feature +0 -2
  207. data/features/code_check/W0700.feature +0 -2
  208. data/features/code_check/W0703.feature +0 -2
  209. data/features/code_check/W0705.feature +6 -2
  210. data/features/code_check/W0707.feature +4 -2
  211. data/features/code_check/W0711.feature +0 -2
  212. data/features/code_check/W0712.feature +0 -2
  213. data/features/code_check/W0713.feature +0 -2
  214. data/features/code_check/W0714.feature +0 -2
  215. data/features/code_check/W0715.feature +0 -2
  216. data/features/code_check/W0716.feature +0 -2
  217. data/features/code_check/W0717.feature +0 -2
  218. data/features/code_check/W0718.feature +0 -2
  219. data/features/code_check/W0719.feature +0 -2
  220. data/features/code_check/W0723.feature +0 -2
  221. data/features/code_check/W0726.feature +0 -2
  222. data/features/code_check/W0732.feature +0 -2
  223. data/features/code_check/W0733.feature +0 -2
  224. data/features/code_check/W0734.feature +0 -2
  225. data/features/code_check/W0735.feature +0 -2
  226. data/features/code_check/W0745.feature +1 -2
  227. data/features/code_check/W0747.feature +0 -2
  228. data/features/code_check/W0748.feature +0 -2
  229. data/features/code_check/W0749.feature +0 -2
  230. data/features/code_check/W0750.feature +0 -2
  231. data/features/code_check/W0751.feature +0 -2
  232. data/features/code_check/W0752.feature +0 -2
  233. data/features/code_check/W0753.feature +0 -2
  234. data/features/code_check/W0754.feature +0 -2
  235. data/features/code_check/W0755.feature +0 -2
  236. data/features/code_check/W0756.feature +0 -2
  237. data/features/code_check/W0757.feature +0 -2
  238. data/features/code_check/W0758.feature +0 -2
  239. data/features/code_check/W0759.feature +0 -2
  240. data/features/code_check/W0760.feature +0 -2
  241. data/features/code_check/W0761.feature +0 -2
  242. data/features/code_check/W0762.feature +0 -2
  243. data/features/code_check/W0763.feature +0 -2
  244. data/features/code_check/W0764.feature +0 -2
  245. data/features/code_check/W0765.feature +0 -2
  246. data/features/code_check/W0766.feature +0 -2
  247. data/features/code_check/W0767.feature +0 -2
  248. data/features/code_check/W0768.feature +0 -2
  249. data/features/code_check/W0769.feature +0 -2
  250. data/features/code_check/W0780.feature +0 -2
  251. data/features/code_check/W0781.feature +0 -2
  252. data/features/code_check/W0783.feature +0 -2
  253. data/features/code_check/W0787.feature +0 -2
  254. data/features/code_check/W0792.feature +0 -2
  255. data/features/code_check/W0793.feature +0 -2
  256. data/features/code_check/W0794.feature +0 -2
  257. data/features/code_check/W0801.feature +0 -2
  258. data/features/code_check/W0805.feature +0 -2
  259. data/features/code_check/W0806.feature +0 -2
  260. data/features/code_check/W0807.feature +0 -2
  261. data/features/code_check/W0808.feature +0 -2
  262. data/features/code_check/W0809.feature +0 -2
  263. data/features/code_check/W0811.feature +0 -2
  264. data/features/code_check/W0830.feature +0 -2
  265. data/features/code_check/W0833.feature +0 -2
  266. data/features/code_check/W0834.feature +1 -3
  267. data/features/code_check/W1026.feature +0 -2
  268. data/features/code_check/W1030.feature +0 -2
  269. data/features/code_check/W1031.feature +0 -2
  270. data/features/code_check/W1039.feature +0 -2
  271. data/features/code_check/W1040.feature +0 -2
  272. data/features/code_check/W1041.feature +0 -2
  273. data/features/code_check/W1046.feature +0 -2
  274. data/features/code_check/W1047.feature +0 -2
  275. data/features/code_check/W1052.feature +0 -2
  276. data/features/code_check/W1066.feature +0 -2
  277. data/features/code_check/W1067.feature +0 -2
  278. data/features/code_check/W1068.feature +0 -2
  279. data/features/code_check/W1069.feature +0 -2
  280. data/features/code_check/W1070.feature +0 -2
  281. data/features/code_check/W1071.feature +0 -2
  282. data/features/code_check/W1072.feature +0 -2
  283. data/features/code_check/W1073.feature +1 -3
  284. data/features/code_check/W1074.feature +3 -4
  285. data/features/code_check/W1075.feature +0 -2
  286. data/features/code_check/W1076.feature +0 -2
  287. data/features/code_check/W1077.feature +0 -2
  288. data/features/code_check/W9001.feature +0 -2
  289. data/features/code_check/W9003.feature +3 -3
  290. data/lib/adlint/c/branch.rb +2 -2
  291. data/lib/adlint/c/environ.rb +3 -3
  292. data/lib/adlint/c/expr.rb +67 -39
  293. data/lib/adlint/c/interp.rb +10 -1
  294. data/lib/adlint/c/object.rb +6 -4
  295. data/lib/adlint/c/parser.rb +1 -1
  296. data/lib/adlint/c/value.rb +27 -10
  297. data/lib/adlint/cpp/constexpr.rb +1 -1
  298. data/lib/adlint/exam/c_builtin/c_check.rb +502 -420
  299. data/lib/adlint/version.rb +2 -2
  300. data/share/doc/developers_guide_ja.html +3 -3
  301. data/share/doc/developers_guide_ja.texi +1 -1
  302. data/share/doc/users_guide_en.html +10 -10
  303. data/share/doc/users_guide_en.texi +8 -8
  304. data/share/doc/users_guide_ja.html +10 -10
  305. data/share/doc/users_guide_ja.texi +8 -8
  306. metadata +15 -3
@@ -2782,7 +2782,7 @@ module CBuiltin #:nodoc:
2782
2782
  end
2783
2783
 
2784
2784
  class W0120 < W0119
2785
- def_registrant_phase C::Prepare2Phase
2785
+ def_registrant_phase C::Prepare2Phase
2786
2786
 
2787
2787
  private
2788
2788
  def from_type
@@ -7835,6 +7835,10 @@ module CBuiltin #:nodoc:
7835
7835
  class W0488 < PassiveCodeCheck
7836
7836
  def_registrant_phase C::Prepare2Phase
7837
7837
 
7838
+ # NOTE: W0488 may be duplicative when problematic operators appear thrice
7839
+ # or more in an expression.
7840
+ ensure_uniqueness_of :W0488
7841
+
7838
7842
  def initialize(context)
7839
7843
  super
7840
7844
  visitor = context[:c_visitor]
@@ -7906,11 +7910,10 @@ module CBuiltin #:nodoc:
7906
7910
  def initialize(context, expression)
7907
7911
  @context = context
7908
7912
  @expression = expression
7909
- @already_warned = false
7910
- @group_depth = 0
7911
- @ungrouped_array_subscript_expr = 0
7912
- @ungrouped_function_call_expr = 0
7913
- @ungrouped_member_access_expr = 0
7913
+ @enclosure_expr_stack = [expression]
7914
+ @ary_subscript_exprs = Hash.new(0)
7915
+ @function_call_exprs = Hash.new(0)
7916
+ @member_access_exprs = Hash.new(0)
7914
7917
  end
7915
7918
 
7916
7919
  def execute
@@ -7918,20 +7921,20 @@ module CBuiltin #:nodoc:
7918
7921
  end
7919
7922
 
7920
7923
  def visit_grouped_expression(node)
7921
- @group_depth += 1
7924
+ @enclosure_expr_stack.push(node)
7922
7925
  super
7923
- @group_depth -= 1
7926
+ @enclosure_expr_stack.pop
7924
7927
  end
7925
7928
 
7926
7929
  def visit_array_subscript_expression(node)
7927
7930
  node.expression.accept(self)
7928
- @ungrouped_array_subscript_expr += 1 if @group_depth == 0
7931
+ @ary_subscript_exprs[current_enclosure_expr] += 1
7929
7932
  AmbiguousExpressionDetector.new(@context, node.array_subscript).execute
7930
7933
  end
7931
7934
 
7932
7935
  def visit_function_call_expression(node)
7933
7936
  node.expression.accept(self)
7934
- @ungrouped_function_call_expr += 1 if @group_depth == 0
7937
+ @function_call_exprs[current_enclosure_expr] += 1
7935
7938
  node.argument_expressions.each do |expr|
7936
7939
  AmbiguousExpressionDetector.new(@context, expr).execute
7937
7940
  end
@@ -7939,49 +7942,53 @@ module CBuiltin #:nodoc:
7939
7942
 
7940
7943
  def visit_member_access_by_value_expression(node)
7941
7944
  super
7942
- @ungrouped_member_access_expr += 1 if @group_depth == 0
7945
+ @member_access_exprs[current_enclosure_expr] += 1
7943
7946
  end
7944
7947
 
7945
7948
  def visit_member_access_by_pointer_expression(node)
7946
7949
  super
7947
- @ungrouped_member_access_expr += 1 if @group_depth == 0
7950
+ @member_access_exprs[current_enclosure_expr] += 1
7948
7951
  end
7949
7952
 
7950
7953
  def visit_bit_access_by_value_expression(node)
7951
7954
  super
7952
- @ungrouped_member_access_expr += 1 if @group_depth == 0
7955
+ @member_access_exprs[current_enclosure_expr] += 1
7953
7956
  end
7954
7957
 
7955
7958
  def visit_bit_access_by_pointer_expression(node)
7956
7959
  super
7957
- @ungrouped_member_access_expr += 1 if @group_depth == 0
7960
+ @member_access_exprs[current_enclosure_expr] += 1
7958
7961
  end
7959
7962
 
7960
7963
  def visit_logical_and_expression(node)
7961
7964
  super
7962
- unless @already_warned
7963
- if include_ambiguous_expr?
7964
- W(:W0488, @expression.head_location)
7965
- @already_warned = true
7966
- end
7965
+ if include_ambiguous_expr?
7966
+ W(:W0488, current_enclosure_expr.head_location)
7967
7967
  end
7968
7968
  end
7969
7969
 
7970
7970
  def visit_logical_or_expression(node)
7971
7971
  super
7972
- unless @already_warned
7973
- if include_ambiguous_expr?
7974
- W(:W0488, @expression.head_location)
7975
- @already_warned = true
7976
- end
7972
+ if include_ambiguous_expr?
7973
+ W(:W0488, current_enclosure_expr.head_location)
7977
7974
  end
7978
7975
  end
7979
7976
 
7977
+ def visit_conditional_expression(node)
7978
+ AmbiguousExpressionDetector.new(@context, node.condition).execute
7979
+ AmbiguousExpressionDetector.new(@context, node.then_expression).execute
7980
+ AmbiguousExpressionDetector.new(@context, node.else_expression).execute
7981
+ end
7982
+
7980
7983
  private
7981
7984
  def include_ambiguous_expr?
7982
- @ungrouped_array_subscript_expr > 0 ||
7983
- @ungrouped_function_call_expr > 0 ||
7984
- @ungrouped_member_access_expr > 0
7985
+ @ary_subscript_exprs[current_enclosure_expr] > 0 or
7986
+ @function_call_exprs[current_enclosure_expr] > 0 or
7987
+ @member_access_exprs[current_enclosure_expr] > 0
7988
+ end
7989
+
7990
+ def current_enclosure_expr
7991
+ @enclosure_expr_stack.last
7985
7992
  end
7986
7993
 
7987
7994
  def report
@@ -7994,6 +8001,10 @@ module CBuiltin #:nodoc:
7994
8001
  class W0489 < PassiveCodeCheck
7995
8002
  def_registrant_phase C::Prepare2Phase
7996
8003
 
8004
+ # NOTE: W0489 may be duplicative when operators of the same priority are
8005
+ # used thrice or more.
8006
+ ensure_uniqueness_of :W0489
8007
+
7997
8008
  def initialize(context)
7998
8009
  super
7999
8010
  visitor = context[:c_visitor]
@@ -8065,9 +8076,8 @@ module CBuiltin #:nodoc:
8065
8076
  def initialize(context, expression)
8066
8077
  @context = context
8067
8078
  @expression = expression
8068
- @already_warned = false
8069
- @group_depth = 0
8070
- @ungrouped_unary_expr = 0
8079
+ @enclosure_expr_stack = [expression]
8080
+ @unary_exprs = Hash.new(0)
8071
8081
  end
8072
8082
 
8073
8083
  def execute
@@ -8075,84 +8085,88 @@ module CBuiltin #:nodoc:
8075
8085
  end
8076
8086
 
8077
8087
  def visit_grouped_expression(node)
8078
- @group_depth += 1
8088
+ @enclosure_expr_stack.push(node)
8079
8089
  super
8080
- @group_depth -= 1
8090
+ @enclosure_expr_stack.pop
8081
8091
  end
8082
8092
 
8083
8093
  def visit_postfix_increment_expression(node)
8084
8094
  super
8085
- @ungrouped_unary_expr += 1 if @group_depth == 0
8095
+ @unary_exprs[current_enclosure_expr] += 1
8086
8096
  end
8087
8097
 
8088
8098
  def visit_postfix_decrement_expression(node)
8089
8099
  super
8090
- @ungrouped_unary_expr += 1 if @group_depth == 0
8100
+ @unary_exprs[current_enclosure_expr] += 1
8091
8101
  end
8092
8102
 
8093
8103
  def visit_prefix_increment_expression(node)
8094
8104
  super
8095
- @ungrouped_unary_expr += 1 if @group_depth == 0
8105
+ @unary_exprs[current_enclosure_expr] += 1
8096
8106
  end
8097
8107
 
8098
8108
  def visit_prefix_decrement_expression(node)
8099
8109
  super
8100
- @ungrouped_unary_expr += 1 if @group_depth == 0
8110
+ @unary_exprs[current_enclosure_expr] += 1
8101
8111
  end
8102
8112
 
8103
8113
  def visit_address_expression(node)
8104
8114
  super
8105
- @ungrouped_unary_expr += 1 if @group_depth == 0
8115
+ @unary_exprs[current_enclosure_expr] += 1
8106
8116
  end
8107
8117
 
8108
8118
  def visit_indirection_expression(node)
8109
8119
  super
8110
- @ungrouped_unary_expr += 1 if @group_depth == 0
8120
+ @unary_exprs[current_enclosure_expr] += 1
8111
8121
  end
8112
8122
 
8113
8123
  def visit_unary_arithmetic_expression(node)
8114
8124
  super
8115
- @ungrouped_unary_expr += 1 if @group_depth == 0
8125
+ @unary_exprs[current_enclosure_expr] += 1
8116
8126
  end
8117
8127
 
8118
8128
  def visit_sizeof_expression(node)
8119
8129
  super
8120
- @ungrouped_unary_expr += 1 if @group_depth == 0
8130
+ @unary_exprs[current_enclosure_expr] += 1
8121
8131
  end
8122
8132
 
8123
8133
  def visit_alignof_expression(node)
8124
8134
  super
8125
- @ungrouped_unary_expr += 1 if @group_depth == 0
8135
+ @unary_exprs[current_enclosure_expr] += 1
8126
8136
  end
8127
8137
 
8128
8138
  def visit_cast_expression(node)
8129
8139
  node.operand.accept(self)
8130
- @ungrouped_unary_expr += 1 if @group_depth == 0
8140
+ @unary_exprs[current_enclosure_expr] += 1
8131
8141
  end
8132
8142
 
8133
8143
  def visit_logical_and_expression(node)
8134
8144
  super
8135
- unless @already_warned
8136
- if include_ambiguous_expr?
8137
- W(:W0489, @expression.head_location)
8138
- @already_warned = true
8139
- end
8145
+ if include_ambiguous_expr?
8146
+ W(:W0489, current_enclosure_expr.head_location)
8140
8147
  end
8141
8148
  end
8142
8149
 
8143
8150
  def visit_logical_or_expression(node)
8144
8151
  super
8145
- unless @already_warned
8146
- if include_ambiguous_expr?
8147
- W(:W0489, @expression.head_location)
8148
- @already_warned = true
8149
- end
8152
+ if include_ambiguous_expr?
8153
+ W(:W0489, current_enclosure_expr.head_location)
8150
8154
  end
8151
8155
  end
8152
8156
 
8157
+ def visit_conditional_expression(node)
8158
+ AmbiguousExpressionDetector.new(@context, node.condition).execute
8159
+ AmbiguousExpressionDetector.new(@context, node.then_expression).execute
8160
+ AmbiguousExpressionDetector.new(@context, node.else_expression).execute
8161
+ end
8162
+
8153
8163
  private
8154
8164
  def include_ambiguous_expr?
8155
- @ungrouped_unary_expr > 0
8165
+ @unary_exprs[current_enclosure_expr] > 0
8166
+ end
8167
+
8168
+ def current_enclosure_expr
8169
+ @enclosure_expr_stack.last
8156
8170
  end
8157
8171
 
8158
8172
  def report
@@ -8165,6 +8179,10 @@ module CBuiltin #:nodoc:
8165
8179
  class W0490 < PassiveCodeCheck
8166
8180
  def_registrant_phase C::Prepare2Phase
8167
8181
 
8182
+ # NOTE: W0490 may be duplicative when problematic operators appear thrice
8183
+ # or more in an expression.
8184
+ ensure_uniqueness_of :W0490
8185
+
8168
8186
  def initialize(context)
8169
8187
  super
8170
8188
  visitor = context[:c_visitor]
@@ -8236,10 +8254,9 @@ module CBuiltin #:nodoc:
8236
8254
  def initialize(context, expression)
8237
8255
  @context = context
8238
8256
  @expression = expression
8239
- @already_warned = false
8240
- @group_depth = 0
8241
- @ungrouped_highprec_binary_expr = 0
8242
- @ungrouped_logical_and_expr = 0
8257
+ @enclosure_expr_stack = [expression]
8258
+ @highprec_binary_exprs = Hash.new(0)
8259
+ @logical_and_exprs = Hash.new(0)
8243
8260
  end
8244
8261
 
8245
8262
  def execute
@@ -8247,9 +8264,9 @@ module CBuiltin #:nodoc:
8247
8264
  end
8248
8265
 
8249
8266
  def visit_grouped_expression(node)
8250
- @group_depth += 1
8267
+ @enclosure_expr_stack.push(node)
8251
8268
  super
8252
- @group_depth -= 1
8269
+ @enclosure_expr_stack.pop
8253
8270
  end
8254
8271
 
8255
8272
  def visit_array_subscript_expression(node)
@@ -8266,67 +8283,72 @@ module CBuiltin #:nodoc:
8266
8283
 
8267
8284
  def visit_multiplicative_expression(node)
8268
8285
  super
8269
- @ungrouped_highprec_binary_expr += 1 if @group_depth == 0
8286
+ @highprec_binary_exprs[current_enclosure_expr] += 1
8270
8287
  end
8271
8288
 
8272
8289
  def visit_additive_expression(node)
8273
8290
  super
8274
- @ungrouped_highprec_binary_expr += 1 if @group_depth == 0
8291
+ @highprec_binary_exprs[current_enclosure_expr] += 1
8275
8292
  end
8276
8293
 
8277
8294
  def visit_shift_expression(node)
8278
8295
  super
8279
- @ungrouped_highprec_binary_expr += 1 if @group_depth == 0
8296
+ @highprec_binary_exprs[current_enclosure_expr] += 1
8280
8297
  end
8281
8298
 
8282
8299
  def visit_relational_expression(node)
8283
8300
  super
8284
- @ungrouped_highprec_binary_expr += 1 if @group_depth == 0
8301
+ @highprec_binary_exprs[current_enclosure_expr] += 1
8285
8302
  end
8286
8303
 
8287
8304
  def visit_equality_expression(node)
8288
8305
  super
8289
- @ungrouped_highprec_binary_expr += 1 if @group_depth == 0
8306
+ @highprec_binary_exprs[current_enclosure_expr] += 1
8290
8307
  end
8291
8308
 
8292
8309
  def visit_and_expression(node)
8293
8310
  super
8294
- @ungrouped_highprec_binary_expr += 1 if @group_depth == 0
8311
+ @highprec_binary_exprs[current_enclosure_expr] += 1
8295
8312
  end
8296
8313
 
8297
8314
  def visit_exclusive_or_expression(node)
8298
8315
  super
8299
- @ungrouped_highprec_binary_expr += 1 if @group_depth == 0
8316
+ @highprec_binary_exprs[current_enclosure_expr] += 1
8300
8317
  end
8301
8318
 
8302
8319
  def visit_inclusive_or_expression(node)
8303
8320
  super
8304
- @ungrouped_highprec_binary_expr += 1 if @group_depth == 0
8321
+ @highprec_binary_exprs[current_enclosure_expr] += 1
8305
8322
  end
8306
8323
 
8307
8324
  def visit_logical_and_expression(node)
8308
8325
  super
8309
- @ungrouped_logical_and_expr += 1 if @group_depth == 0
8310
-
8311
- unless @already_warned
8312
- if @ungrouped_highprec_binary_expr > 0
8313
- W(:W0490, @expression.head_location)
8314
- @already_warned = true
8315
- end
8326
+ current_enclosure = current_enclosure_expr
8327
+ @logical_and_exprs[current_enclosure] += 1
8328
+ if @highprec_binary_exprs[current_enclosure] > 0
8329
+ W(:W0490, current_enclosure.head_location)
8316
8330
  end
8317
8331
  end
8318
8332
 
8319
8333
  def visit_logical_or_expression(node)
8320
8334
  super
8321
- unless @already_warned
8322
- if @ungrouped_highprec_binary_expr + @ungrouped_logical_and_expr > 0
8323
- W(:W0490, @expression.head_location)
8324
- @already_warned = true
8325
- end
8335
+ encl = current_enclosure_expr
8336
+ if @highprec_binary_exprs[encl] + @logical_and_exprs[encl] > 0
8337
+ W(:W0490, encl.head_location)
8326
8338
  end
8327
8339
  end
8328
8340
 
8341
+ def visit_conditional_expression(node)
8342
+ AmbiguousExpressionDetector.new(@context, node.condition).execute
8343
+ AmbiguousExpressionDetector.new(@context, node.then_expression).execute
8344
+ AmbiguousExpressionDetector.new(@context, node.else_expression).execute
8345
+ end
8346
+
8329
8347
  private
8348
+ def current_enclosure_expr
8349
+ @enclosure_expr_stack.last
8350
+ end
8351
+
8330
8352
  def report
8331
8353
  @context.report
8332
8354
  end
@@ -8705,6 +8727,10 @@ module CBuiltin #:nodoc:
8705
8727
  class W0495 < PassiveCodeCheck
8706
8728
  def_registrant_phase C::Prepare2Phase
8707
8729
 
8730
+ # NOTE: W0495 may be duplicative when problematic operators appear thrice
8731
+ # or more in an expression.
8732
+ ensure_uniqueness_of :W0495
8733
+
8708
8734
  def initialize(context)
8709
8735
  super
8710
8736
  visitor = context[:c_visitor]
@@ -8776,12 +8802,12 @@ module CBuiltin #:nodoc:
8776
8802
  def initialize(context, expression)
8777
8803
  @context = context
8778
8804
  @expression = expression
8779
- @group_depth = 0
8780
- @ungrouped_add_expr = 0
8781
- @ungrouped_sub_expr = 0
8782
- @ungrouped_mul_expr = 0
8783
- @ungrouped_div_expr = 0
8784
- @ungrouped_mod_expr = 0
8805
+ @enclosure_expr_stack = [expression]
8806
+ @add_exprs = Hash.new(0)
8807
+ @sub_exprs = Hash.new(0)
8808
+ @mul_exprs = Hash.new(0)
8809
+ @div_exprs = Hash.new(0)
8810
+ @mod_exprs = Hash.new(0)
8785
8811
  end
8786
8812
 
8787
8813
  def execute
@@ -8789,9 +8815,9 @@ module CBuiltin #:nodoc:
8789
8815
  end
8790
8816
 
8791
8817
  def visit_grouped_expression(node)
8792
- @group_depth += 1
8818
+ @enclosure_expr_stack.push(node)
8793
8819
  super
8794
- @group_depth -= 1
8820
+ @enclosure_expr_stack.pop
8795
8821
  end
8796
8822
 
8797
8823
  def visit_array_subscript_expression(node)
@@ -8805,51 +8831,56 @@ module CBuiltin #:nodoc:
8805
8831
  end
8806
8832
 
8807
8833
  def visit_additive_expression(node)
8808
- if @group_depth == 0
8809
- case node.operator.type
8810
- when "+"
8811
- @ungrouped_add_expr += 1
8812
- when "-"
8813
- @ungrouped_sub_expr += 1
8814
- end
8815
- end
8816
-
8817
- if include_ambiguous_expr?
8818
- W(:W0495, @expression.head_location)
8819
- else
8820
- super
8834
+ current_enclosure = current_enclosure_expr
8835
+ case node.operator.type
8836
+ when "+"
8837
+ @add_exprs[current_enclosure] += 1
8838
+ W(:W0495, current_enclosure.head_location) if include_ambiguous_expr?
8839
+ when "-"
8840
+ @sub_exprs[current_enclosure] += 1
8841
+ W(:W0495, current_enclosure.head_location) if include_ambiguous_expr?
8821
8842
  end
8843
+ super
8822
8844
  end
8823
8845
 
8824
8846
  def visit_multiplicative_expression(node)
8825
- if @group_depth == 0
8826
- case node.operator.type
8827
- when "*"
8828
- @ungrouped_mul_expr += 1
8829
- when "/"
8830
- @ungrouped_div_expr += 1
8831
- when "%"
8832
- @ungrouped_mod_expr += 1
8833
- end
8847
+ current_enclosure = current_enclosure_expr
8848
+ case node.operator.type
8849
+ when "*"
8850
+ @mul_exprs[current_enclosure] += 1
8851
+ W(:W0495, current_enclosure.head_location) if include_ambiguous_expr?
8852
+ when "/"
8853
+ @div_exprs[current_enclosure] += 1
8854
+ W(:W0495, current_enclosure.head_location) if include_ambiguous_expr?
8855
+ when "%"
8856
+ @mod_exprs[current_enclosure] += 1
8857
+ W(:W0495, current_enclosure.head_location) if include_ambiguous_expr?
8834
8858
  end
8859
+ super
8860
+ end
8835
8861
 
8836
- if include_ambiguous_expr?
8837
- W(:W0495, @expression.head_location)
8838
- else
8839
- super
8840
- end
8862
+ def visit_conditional_expression(node)
8863
+ AmbiguousExpressionDetector.new(@context, node.condition).execute
8864
+ AmbiguousExpressionDetector.new(@context, node.then_expression).execute
8865
+ AmbiguousExpressionDetector.new(@context, node.else_expression).execute
8841
8866
  end
8842
8867
 
8843
8868
  private
8844
8869
  def include_ambiguous_expr?
8845
- return false if @ungrouped_mod_expr == 0
8870
+ enclosure = current_enclosure_expr
8871
+ return false if @mod_exprs[enclosure] == 0
8846
8872
 
8847
- ungrouped_multiplicative_expr =
8848
- @ungrouped_mul_expr + @ungrouped_div_expr + @ungrouped_mod_expr
8873
+ additive_exprs =
8874
+ @add_exprs[enclosure] + @sub_exprs[enclosure]
8875
+ multiplicative_exprs =
8876
+ @mul_exprs[enclosure] + @div_exprs[enclosure] + @mod_exprs[enclosure]
8849
8877
 
8850
- (@ungrouped_add_expr + @ungrouped_sub_expr) > 0 &&
8851
- ungrouped_multiplicative_expr > 0 or
8852
- ungrouped_multiplicative_expr > 1
8878
+ additive_exprs > 0 && multiplicative_exprs > 0 or
8879
+ multiplicative_exprs > 1
8880
+ end
8881
+
8882
+ def current_enclosure_expr
8883
+ @enclosure_expr_stack.last
8853
8884
  end
8854
8885
 
8855
8886
  def report
@@ -8862,6 +8893,10 @@ module CBuiltin #:nodoc:
8862
8893
  class W0496 < PassiveCodeCheck
8863
8894
  def_registrant_phase C::Prepare2Phase
8864
8895
 
8896
+ # NOTE: W0496 may be duplicative when problematic operators appear thrice
8897
+ # or more in an expression.
8898
+ ensure_uniqueness_of :W0496
8899
+
8865
8900
  def initialize(context)
8866
8901
  super
8867
8902
  visitor = context[:c_visitor]
@@ -8935,9 +8970,8 @@ module CBuiltin #:nodoc:
8935
8970
  def initialize(context, expression)
8936
8971
  @context = context
8937
8972
  @expression = expression
8938
- @already_warned = false
8939
- @group_depth = 0
8940
- @ungrouped_conditional_expr = 0
8973
+ @enclosure_expr_stack = [expression]
8974
+ @conditional_exprs = Hash.new(0)
8941
8975
  end
8942
8976
 
8943
8977
  def execute
@@ -8945,23 +8979,25 @@ module CBuiltin #:nodoc:
8945
8979
  end
8946
8980
 
8947
8981
  def visit_grouped_expression(node)
8948
- @group_depth += 1
8982
+ @enclosure_expr_stack.push(node)
8949
8983
  super
8950
- @group_depth -= 1
8984
+ @enclosure_expr_stack.pop
8951
8985
  end
8952
8986
 
8953
8987
  def visit_conditional_expression(node)
8954
8988
  super
8955
- unless @already_warned
8956
- if @ungrouped_conditional_expr > 0
8957
- W(:W0496, @expression.head_location)
8958
- @already_warned = true
8959
- end
8989
+ current_enclosure = current_enclosure_expr
8990
+ if @conditional_exprs[current_enclosure] > 0
8991
+ W(:W0496, current_enclosure.head_location)
8960
8992
  end
8961
- @ungrouped_conditional_expr += 1 if @group_depth == 0
8993
+ @conditional_exprs[current_enclosure] += 1
8962
8994
  end
8963
8995
 
8964
8996
  private
8997
+ def current_enclosure_expr
8998
+ @enclosure_expr_stack.last
8999
+ end
9000
+
8965
9001
  def report
8966
9002
  @context.report
8967
9003
  end
@@ -8972,6 +9008,10 @@ module CBuiltin #:nodoc:
8972
9008
  class W0497 < PassiveCodeCheck
8973
9009
  def_registrant_phase C::Prepare2Phase
8974
9010
 
9011
+ # NOTE: W0497 may be duplicative when problematic operators appear thrice
9012
+ # or more in an expression.
9013
+ ensure_uniqueness_of :W0497
9014
+
8975
9015
  def initialize(context)
8976
9016
  super
8977
9017
  visitor = context[:c_visitor]
@@ -9043,15 +9083,15 @@ module CBuiltin #:nodoc:
9043
9083
  def initialize(context, expression)
9044
9084
  @context = context
9045
9085
  @expression = expression
9046
- @group_depth = 0
9047
- @ungrouped_shr_expr = 0
9048
- @ungrouped_shl_expr = 0
9049
- @ungrouped_lt_expr = 0
9050
- @ungrouped_gt_expr = 0
9051
- @ungrouped_le_expr = 0
9052
- @ungrouped_ge_expr = 0
9053
- @ungrouped_eq_expr = 0
9054
- @ungrouped_ne_expr = 0
9086
+ @enclosure_expr_stack = [expression]
9087
+ @shr_exprs = Hash.new(0)
9088
+ @shl_exprs = Hash.new(0)
9089
+ @lt_exprs = Hash.new(0)
9090
+ @gt_exprs = Hash.new(0)
9091
+ @le_exprs = Hash.new(0)
9092
+ @ge_exprs = Hash.new(0)
9093
+ @eq_exprs = Hash.new(0)
9094
+ @ne_exprs = Hash.new(0)
9055
9095
  end
9056
9096
 
9057
9097
  def execute
@@ -9059,9 +9099,9 @@ module CBuiltin #:nodoc:
9059
9099
  end
9060
9100
 
9061
9101
  def visit_grouped_expression(node)
9062
- @group_depth += 1
9102
+ @enclosure_expr_stack.push(node)
9063
9103
  super
9064
- @group_depth -= 1
9104
+ @enclosure_expr_stack.pop
9065
9105
  end
9066
9106
 
9067
9107
  def visit_array_subscript_expression(node)
@@ -9075,66 +9115,67 @@ module CBuiltin #:nodoc:
9075
9115
  end
9076
9116
 
9077
9117
  def visit_shift_expression(node)
9078
- if @group_depth == 0
9079
- case node.operator.type
9080
- when "<<"
9081
- @ungrouped_shl_expr += 1
9082
- when ">>"
9083
- @ungrouped_shr_expr += 1
9084
- end
9085
- end
9086
-
9087
- if include_ambiguous_expr?
9088
- W(:W0497, @expression.head_location)
9089
- else
9090
- super
9118
+ current_enclosure = current_enclosure_expr
9119
+ case node.operator.type
9120
+ when "<<"
9121
+ @shl_exprs[current_enclosure] += 1
9122
+ W(:W0497, current_enclosure.head_location) if include_ambiguous_expr?
9123
+ when ">>"
9124
+ @shr_exprs[current_enclosure] += 1
9125
+ W(:W0497, current_enclosure.head_location) if include_ambiguous_expr?
9091
9126
  end
9127
+ super
9092
9128
  end
9093
9129
 
9094
9130
  def visit_relational_expression(node)
9095
- if @group_depth == 0
9096
- case node.operator.type
9097
- when "<"
9098
- @ungrouped_lt_expr += 1
9099
- when ">"
9100
- @ungrouped_gt_expr += 1
9101
- when "<="
9102
- @ungrouped_le_expr += 1
9103
- when ">="
9104
- @ungrouped_ge_expr += 1
9105
- end
9106
- end
9107
-
9108
- if include_ambiguous_expr?
9109
- W(:W0497, @expression.head_location)
9110
- else
9111
- super
9131
+ current_enclosure = current_enclosure_expr
9132
+ case node.operator.type
9133
+ when "<"
9134
+ @lt_exprs[current_enclosure] += 1
9135
+ W(:W0497, current_enclosure.head_location) if include_ambiguous_expr?
9136
+ when ">"
9137
+ @gt_exprs[current_enclosure] += 1
9138
+ W(:W0497, current_enclosure.head_location) if include_ambiguous_expr?
9139
+ when "<="
9140
+ @le_exprs[current_enclosure] += 1
9141
+ W(:W0497, current_enclosure.head_location) if include_ambiguous_expr?
9142
+ when ">="
9143
+ @ge_exprs[current_enclosure] += 1
9144
+ W(:W0497, current_enclosure.head_location) if include_ambiguous_expr?
9112
9145
  end
9146
+ super
9113
9147
  end
9114
9148
 
9115
9149
  def visit_equality_expression(node)
9116
- if @group_depth == 0
9117
- case node.operator.type
9118
- when "=="
9119
- @ungrouped_eq_expr += 1
9120
- when "!="
9121
- @ungrouped_ne_expr += 1
9122
- end
9150
+ current_enclosure = current_enclosure_expr
9151
+ case node.operator.type
9152
+ when "=="
9153
+ @eq_exprs[current_enclosure] += 1
9154
+ W(:W0497, current_enclosure.head_location) if include_ambiguous_expr?
9155
+ when "!="
9156
+ @ne_exprs[current_enclosure] += 1
9157
+ W(:W0497, current_enclosure.head_location) if include_ambiguous_expr?
9123
9158
  end
9159
+ super
9160
+ end
9124
9161
 
9125
- if include_ambiguous_expr?
9126
- W(:W0497, @expression.head_location)
9127
- else
9128
- super
9129
- end
9162
+ def visit_conditional_expression(node)
9163
+ AmbiguousExpressionDetector.new(@context, node.condition).execute
9164
+ AmbiguousExpressionDetector.new(@context, node.then_expression).execute
9165
+ AmbiguousExpressionDetector.new(@context, node.else_expression).execute
9130
9166
  end
9131
9167
 
9132
9168
  private
9133
9169
  def include_ambiguous_expr?
9134
- @ungrouped_shl_expr > 1 || @ungrouped_shr_expr > 1 ||
9135
- @ungrouped_lt_expr > 1 || @ungrouped_gt_expr > 1 ||
9136
- @ungrouped_le_expr > 1 || @ungrouped_ge_expr > 1 ||
9137
- @ungrouped_eq_expr > 1 || @ungrouped_ne_expr > 1
9170
+ enclosure = current_enclosure_expr
9171
+ @shl_exprs[enclosure] > 1 || @shr_exprs[enclosure] > 1 ||
9172
+ @lt_exprs[enclosure] > 1 || @gt_exprs[enclosure] > 1 ||
9173
+ @le_exprs[enclosure] > 1 || @ge_exprs[enclosure] > 1 ||
9174
+ @eq_exprs[enclosure] > 1 || @ne_exprs[enclosure] > 1
9175
+ end
9176
+
9177
+ def current_enclosure_expr
9178
+ @enclosure_expr_stack.last
9138
9179
  end
9139
9180
 
9140
9181
  def report
@@ -9147,6 +9188,10 @@ module CBuiltin #:nodoc:
9147
9188
  class W0498 < PassiveCodeCheck
9148
9189
  def_registrant_phase C::Prepare2Phase
9149
9190
 
9191
+ # NOTE: W0498 may be duplicative when operators of the same priority are
9192
+ # used thrice or more.
9193
+ ensure_uniqueness_of :W0498
9194
+
9150
9195
  def initialize(context)
9151
9196
  super
9152
9197
  visitor = context[:c_visitor]
@@ -9218,11 +9263,11 @@ module CBuiltin #:nodoc:
9218
9263
  def initialize(context, expression)
9219
9264
  @context = context
9220
9265
  @expression = expression
9221
- @group_depth = 0
9222
- @ungrouped_add_expr = 0
9223
- @ungrouped_sub_expr = 0
9224
- @ungrouped_mul_expr = 0
9225
- @ungrouped_div_expr = 0
9266
+ @enclosure_expr_stack = [expression]
9267
+ @add_exprs = Hash.new(0)
9268
+ @sub_exprs = Hash.new(0)
9269
+ @mul_exprs = Hash.new(0)
9270
+ @div_exprs = Hash.new(0)
9226
9271
  end
9227
9272
 
9228
9273
  def execute
@@ -9230,9 +9275,9 @@ module CBuiltin #:nodoc:
9230
9275
  end
9231
9276
 
9232
9277
  def visit_grouped_expression(node)
9233
- @group_depth += 1
9278
+ @enclosure_expr_stack.push(node)
9234
9279
  super
9235
- @group_depth -= 1
9280
+ @enclosure_expr_stack.pop
9236
9281
  end
9237
9282
 
9238
9283
  def visit_array_subscript_expression(node)
@@ -9246,43 +9291,46 @@ module CBuiltin #:nodoc:
9246
9291
  end
9247
9292
 
9248
9293
  def visit_additive_expression(node)
9249
- if @group_depth == 0
9250
- case node.operator.type
9251
- when "+"
9252
- @ungrouped_add_expr += 1
9253
- when "-"
9254
- @ungrouped_sub_expr += 1
9255
- end
9256
- end
9257
-
9258
- if include_ambiguous_expr?
9259
- W(:W0498, @expression.head_location)
9260
- else
9261
- super
9294
+ current_enclosure = current_enclosure_expr
9295
+ case node.operator.type
9296
+ when "+"
9297
+ @add_exprs[current_enclosure] += 1
9298
+ W(:W0498, current_enclosure.head_location) if include_ambiguous_expr?
9299
+ when "-"
9300
+ @sub_exprs[current_enclosure] += 1
9301
+ W(:W0498, current_enclosure.head_location) if include_ambiguous_expr?
9262
9302
  end
9303
+ super
9263
9304
  end
9264
9305
 
9265
9306
  def visit_multiplicative_expression(node)
9266
- if @group_depth == 0
9267
- case node.operator.type
9268
- when "*"
9269
- @ungrouped_mul_expr += 1
9270
- when "/"
9271
- @ungrouped_div_expr += 1
9272
- end
9307
+ current_enclosure = current_enclosure_expr
9308
+ case node.operator.type
9309
+ when "*"
9310
+ @mul_exprs[current_enclosure] += 1
9311
+ W(:W0498, current_enclosure.head_location) if include_ambiguous_expr?
9312
+ when "/"
9313
+ @div_exprs[current_enclosure] += 1
9314
+ W(:W0498, current_enclosure.head_location) if include_ambiguous_expr?
9273
9315
  end
9316
+ super
9317
+ end
9274
9318
 
9275
- if include_ambiguous_expr?
9276
- W(:W0498, @expression.head_location)
9277
- else
9278
- super
9279
- end
9319
+ def visit_conditional_expression(node)
9320
+ AmbiguousExpressionDetector.new(@context, node.condition).execute
9321
+ AmbiguousExpressionDetector.new(@context, node.then_expression).execute
9322
+ AmbiguousExpressionDetector.new(@context, node.else_expression).execute
9280
9323
  end
9281
9324
 
9282
9325
  private
9283
9326
  def include_ambiguous_expr?
9284
- @ungrouped_add_expr > 0 && @ungrouped_sub_expr > 0 or
9285
- @ungrouped_mul_expr > 0 && @ungrouped_div_expr > 0
9327
+ enclosure = current_enclosure_expr
9328
+ @add_exprs[enclosure] > 0 && @sub_exprs[enclosure] > 0 or
9329
+ @mul_exprs[enclosure] > 0 && @div_exprs[enclosure] > 0
9330
+ end
9331
+
9332
+ def current_enclosure_expr
9333
+ @enclosure_expr_stack.last
9286
9334
  end
9287
9335
 
9288
9336
  def report
@@ -9295,6 +9343,10 @@ module CBuiltin #:nodoc:
9295
9343
  class W0499 < PassiveCodeCheck
9296
9344
  def_registrant_phase C::Prepare2Phase
9297
9345
 
9346
+ # NOTE: W0499 may be duplicative when operators of the same priority are
9347
+ # used thrice or more.
9348
+ ensure_uniqueness_of :W0499
9349
+
9298
9350
  def initialize(context)
9299
9351
  super
9300
9352
  visitor = context[:c_visitor]
@@ -9366,15 +9418,15 @@ module CBuiltin #:nodoc:
9366
9418
  def initialize(context, expression)
9367
9419
  @context = context
9368
9420
  @expression = expression
9369
- @group_depth = 0
9370
- @ungrouped_shr_expr = 0
9371
- @ungrouped_shl_expr = 0
9372
- @ungrouped_lt_expr = 0
9373
- @ungrouped_gt_expr = 0
9374
- @ungrouped_le_expr = 0
9375
- @ungrouped_ge_expr = 0
9376
- @ungrouped_eq_expr = 0
9377
- @ungrouped_ne_expr = 0
9421
+ @enclosure_expr_stack = [expression]
9422
+ @shr_exprs = Hash.new(0)
9423
+ @shl_exprs = Hash.new(0)
9424
+ @lt_exprs = Hash.new(0)
9425
+ @gt_exprs = Hash.new(0)
9426
+ @le_exprs = Hash.new(0)
9427
+ @ge_exprs = Hash.new(0)
9428
+ @eq_exprs = Hash.new(0)
9429
+ @ne_exprs = Hash.new(0)
9378
9430
  end
9379
9431
 
9380
9432
  def execute
@@ -9382,9 +9434,9 @@ module CBuiltin #:nodoc:
9382
9434
  end
9383
9435
 
9384
9436
  def visit_grouped_expression(node)
9385
- @group_depth += 1
9437
+ @enclosure_expr_stack.push(node)
9386
9438
  super
9387
- @group_depth -= 1
9439
+ @enclosure_expr_stack.pop
9388
9440
  end
9389
9441
 
9390
9442
  def visit_array_subscript_expression(node)
@@ -9398,72 +9450,77 @@ module CBuiltin #:nodoc:
9398
9450
  end
9399
9451
 
9400
9452
  def visit_shift_expression(node)
9401
- if @group_depth == 0
9402
- case node.operator.type
9403
- when "<<"
9404
- @ungrouped_shl_expr += 1
9405
- when ">>"
9406
- @ungrouped_shr_expr += 1
9407
- end
9408
- end
9409
-
9410
- if include_ambiguous_expr?
9411
- W(:W0499, @expression.head_location)
9412
- else
9413
- super
9453
+ current_enclosure = current_enclosure_expr
9454
+ case node.operator.type
9455
+ when "<<"
9456
+ @shl_exprs[current_enclosure] += 1
9457
+ W(:W0499, current_enclosure.head_location) if include_ambiguous_expr?
9458
+ when ">>"
9459
+ @shr_exprs[current_enclosure] += 1
9460
+ W(:W0499, current_enclosure.head_location) if include_ambiguous_expr?
9414
9461
  end
9462
+ super
9415
9463
  end
9416
9464
 
9417
9465
  def visit_relational_expression(node)
9418
- if @group_depth == 0
9419
- case node.operator.type
9420
- when "<"
9421
- @ungrouped_lt_expr += 1
9422
- when ">"
9423
- @ungrouped_gt_expr += 1
9424
- when "<="
9425
- @ungrouped_le_expr += 1
9426
- when ">="
9427
- @ungrouped_ge_expr += 1
9428
- end
9429
- end
9430
-
9431
- if include_ambiguous_expr?
9432
- W(:W0499, @expression.head_location)
9433
- else
9434
- super
9466
+ current_enclosure = current_enclosure_expr
9467
+ case node.operator.type
9468
+ when "<"
9469
+ @lt_exprs[current_enclosure] += 1
9470
+ W(:W0499, current_enclosure.head_location) if include_ambiguous_expr?
9471
+ when ">"
9472
+ @gt_exprs[current_enclosure] += 1
9473
+ W(:W0499, current_enclosure.head_location) if include_ambiguous_expr?
9474
+ when "<="
9475
+ @le_exprs[current_enclosure] += 1
9476
+ W(:W0499, current_enclosure.head_location) if include_ambiguous_expr?
9477
+ when ">="
9478
+ @ge_exprs[current_enclosure] += 1
9479
+ W(:W0499, current_enclosure.head_location) if include_ambiguous_expr?
9435
9480
  end
9481
+ super
9436
9482
  end
9437
9483
 
9438
9484
  def visit_equality_expression(node)
9439
- if @group_depth == 0
9440
- case node.operator.type
9441
- when "=="
9442
- @ungrouped_eq_expr += 1
9443
- when "!="
9444
- @ungrouped_ne_expr += 1
9445
- end
9485
+ current_enclosure = current_enclosure_expr
9486
+ case node.operator.type
9487
+ when "=="
9488
+ @eq_exprs[current_enclosure] += 1
9489
+ W(:W0499, current_enclosure.head_location) if include_ambiguous_expr?
9490
+ when "!="
9491
+ @ne_exprs[current_enclosure] += 1
9492
+ W(:W0499, current_enclosure.head_location) if include_ambiguous_expr?
9446
9493
  end
9494
+ super
9495
+ end
9447
9496
 
9448
- if include_ambiguous_expr?
9449
- W(:W0499, @expression.head_location)
9450
- else
9451
- super
9452
- end
9497
+ def visit_conditional_expression(node)
9498
+ AmbiguousExpressionDetector.new(@context, node.condition).execute
9499
+ AmbiguousExpressionDetector.new(@context, node.then_expression).execute
9500
+ AmbiguousExpressionDetector.new(@context, node.else_expression).execute
9453
9501
  end
9454
9502
 
9455
9503
  private
9456
9504
  def include_ambiguous_expr?
9457
- @ungrouped_shl_expr > 0 && @ungrouped_shr_expr > 0 or
9458
- @ungrouped_lt_expr > 0 &&
9459
- (@ungrouped_gt_expr + @ungrouped_le_expr + @ungrouped_ge_expr) > 0 or
9460
- @ungrouped_gt_expr > 0 &&
9461
- (@ungrouped_lt_expr + @ungrouped_le_expr + @ungrouped_ge_expr) > 0 or
9462
- @ungrouped_le_expr > 0 &&
9463
- (@ungrouped_lt_expr + @ungrouped_gt_expr + @ungrouped_ge_expr) > 0 or
9464
- @ungrouped_ge_expr > 0 &&
9465
- (@ungrouped_lt_expr + @ungrouped_gt_expr + @ungrouped_le_expr) > 0 or
9466
- @ungrouped_eq_expr > 0 && @ungrouped_ne_expr > 0
9505
+ shl_expr_num = @shl_exprs[current_enclosure_expr]
9506
+ shr_expr_num = @shr_exprs[current_enclosure_expr]
9507
+ lt_expr_num = @lt_exprs[current_enclosure_expr]
9508
+ gt_expr_num = @gt_exprs[current_enclosure_expr]
9509
+ le_expr_num = @le_exprs[current_enclosure_expr]
9510
+ ge_expr_num = @ge_exprs[current_enclosure_expr]
9511
+ eq_expr_num = @eq_exprs[current_enclosure_expr]
9512
+ ne_expr_num = @ne_exprs[current_enclosure_expr]
9513
+
9514
+ shl_expr_num > 0 && shr_expr_num > 0 or
9515
+ lt_expr_num > 0 && (gt_expr_num + le_expr_num + ge_expr_num) > 0 or
9516
+ gt_expr_num > 0 && (lt_expr_num + le_expr_num + ge_expr_num) > 0 or
9517
+ le_expr_num > 0 && (lt_expr_num + gt_expr_num + ge_expr_num) > 0 or
9518
+ ge_expr_num > 0 && (lt_expr_num + gt_expr_num + le_expr_num) > 0 or
9519
+ eq_expr_num > 0 && ne_expr_num > 0
9520
+ end
9521
+
9522
+ def current_enclosure_expr
9523
+ @enclosure_expr_stack.last
9467
9524
  end
9468
9525
 
9469
9526
  def report
@@ -9476,6 +9533,10 @@ module CBuiltin #:nodoc:
9476
9533
  class W0500 < PassiveCodeCheck
9477
9534
  def_registrant_phase C::Prepare2Phase
9478
9535
 
9536
+ # NOTE: W0500 may be duplicative when operators of the different priority
9537
+ # are used thrice or more.
9538
+ ensure_uniqueness_of :W0500
9539
+
9479
9540
  def initialize(context)
9480
9541
  super
9481
9542
  visitor = context[:c_visitor]
@@ -9547,11 +9608,11 @@ module CBuiltin #:nodoc:
9547
9608
  def initialize(context, expression)
9548
9609
  @context = context
9549
9610
  @expression = expression
9550
- @group_depth = 0
9551
- @ungrouped_add_expr = 0
9552
- @ungrouped_sub_expr = 0
9553
- @ungrouped_mul_expr = 0
9554
- @ungrouped_div_expr = 0
9611
+ @enclosure_expr_stack = [expression]
9612
+ @add_exprs = Hash.new(0)
9613
+ @sub_exprs = Hash.new(0)
9614
+ @mul_exprs = Hash.new(0)
9615
+ @div_exprs = Hash.new(0)
9555
9616
  end
9556
9617
 
9557
9618
  def execute
@@ -9559,15 +9620,9 @@ module CBuiltin #:nodoc:
9559
9620
  end
9560
9621
 
9561
9622
  def visit_grouped_expression(node)
9562
- @group_depth += 1
9623
+ @enclosure_expr_stack.push(node)
9563
9624
  super
9564
- @group_depth -= 1
9565
- end
9566
-
9567
- def visit_conditional_expression(node)
9568
- @group_depth += 1
9569
- super
9570
- @group_depth -= 1
9625
+ @enclosure_expr_stack.pop
9571
9626
  end
9572
9627
 
9573
9628
  def visit_array_subscript_expression(node)
@@ -9581,43 +9636,46 @@ module CBuiltin #:nodoc:
9581
9636
  end
9582
9637
 
9583
9638
  def visit_multiplicative_expression(node)
9584
- if @group_depth == 0
9585
- case node.operator.type
9586
- when "*"
9587
- @ungrouped_mul_expr += 1
9588
- when "/"
9589
- @ungrouped_div_expr += 1
9590
- end
9591
- end
9592
-
9593
- if include_ambiguous_expr?
9594
- W(:W0500, @expression.head_location)
9595
- else
9596
- super
9639
+ current_enclosure = current_enclosure_expr
9640
+ case node.operator.type
9641
+ when "*"
9642
+ @mul_exprs[current_enclosure] += 1
9643
+ W(:W0500, current_enclosure.head_location) if include_ambiguous_expr?
9644
+ when "/"
9645
+ @div_exprs[current_enclosure] += 1
9646
+ W(:W0500, current_enclosure.head_location) if include_ambiguous_expr?
9597
9647
  end
9648
+ super
9598
9649
  end
9599
9650
 
9600
9651
  def visit_additive_expression(node)
9601
- if @group_depth == 0
9602
- case node.operator.type
9603
- when "+"
9604
- @ungrouped_add_expr += 1
9605
- when "-"
9606
- @ungrouped_sub_expr += 1
9607
- end
9652
+ current_enclosure = current_enclosure_expr
9653
+ case node.operator.type
9654
+ when "+"
9655
+ @add_exprs[current_enclosure] += 1
9656
+ W(:W0500, current_enclosure.head_location) if include_ambiguous_expr?
9657
+ when "-"
9658
+ @sub_exprs[current_enclosure] += 1
9659
+ W(:W0500, current_enclosure.head_location) if include_ambiguous_expr?
9608
9660
  end
9661
+ super
9662
+ end
9609
9663
 
9610
- if include_ambiguous_expr?
9611
- W(:W0500, @expression.head_location)
9612
- else
9613
- super
9614
- end
9664
+ def visit_conditional_expression(node)
9665
+ AmbiguousExpressionDetector.new(@context, node.condition).execute
9666
+ AmbiguousExpressionDetector.new(@context, node.then_expression).execute
9667
+ AmbiguousExpressionDetector.new(@context, node.else_expression).execute
9615
9668
  end
9616
9669
 
9617
9670
  private
9618
9671
  def include_ambiguous_expr?
9619
- (@ungrouped_add_expr + @ungrouped_sub_expr) > 0 &&
9620
- (@ungrouped_mul_expr + @ungrouped_div_expr) > 0
9672
+ current_enclosure = current_enclosure_expr
9673
+ (@add_exprs[current_enclosure] + @sub_exprs[current_enclosure]) > 0 &&
9674
+ (@mul_exprs[current_enclosure] + @div_exprs[current_enclosure]) > 0
9675
+ end
9676
+
9677
+ def current_enclosure_expr
9678
+ @enclosure_expr_stack.last
9621
9679
  end
9622
9680
 
9623
9681
  def report
@@ -9630,6 +9688,10 @@ module CBuiltin #:nodoc:
9630
9688
  class W0501 < PassiveCodeCheck
9631
9689
  def_registrant_phase C::Prepare2Phase
9632
9690
 
9691
+ # NOTE: W0501 may be duplicative when problematic operators appear thrice
9692
+ # or more in an expression.
9693
+ ensure_uniqueness_of :W0501
9694
+
9633
9695
  def initialize(context)
9634
9696
  super
9635
9697
  visitor = context[:c_visitor]
@@ -9703,7 +9765,6 @@ module CBuiltin #:nodoc:
9703
9765
  def initialize(context, expression)
9704
9766
  @context = context
9705
9767
  @expression = expression
9706
- @already_warned = false
9707
9768
  @group_depth = 0
9708
9769
  @ungrouped_binary_expr = 0
9709
9770
  end
@@ -9781,12 +9842,7 @@ module CBuiltin #:nodoc:
9781
9842
  private
9782
9843
  def check_binary_expression
9783
9844
  @ungrouped_binary_expr += 1 if @group_depth == 0
9784
- unless @already_warned
9785
- if include_ambiguous_expr?
9786
- W(:W0501, @expression.head_location)
9787
- @already_warned = true
9788
- end
9789
- end
9845
+ W(:W0501, @expression.location) if include_ambiguous_expr?
9790
9846
  end
9791
9847
 
9792
9848
  def include_ambiguous_expr?
@@ -9803,6 +9859,10 @@ module CBuiltin #:nodoc:
9803
9859
  class W0502 < PassiveCodeCheck
9804
9860
  def_registrant_phase C::Prepare2Phase
9805
9861
 
9862
+ # NOTE: W0502 may be duplicative when operators of the different priority
9863
+ # are used thrice or more.
9864
+ ensure_uniqueness_of :W0502
9865
+
9806
9866
  def initialize(context)
9807
9867
  super
9808
9868
  visitor = context[:c_visitor]
@@ -9874,18 +9934,17 @@ module CBuiltin #:nodoc:
9874
9934
  def initialize(context, expression)
9875
9935
  @context = context
9876
9936
  @expression = expression
9877
- @already_warned = false
9878
- @group_depth = 0
9879
- @ungrouped_multiplicative_expr = 0
9880
- @ungrouped_additive_expr = 0
9881
- @ungrouped_shift_expr = 0
9882
- @ungrouped_relational_expr = 0
9883
- @ungrouped_equality_expr = 0
9884
- @ungrouped_and_expr = 0
9885
- @ungrouped_xor_expr = 0
9886
- @ungrouped_or_expr = 0
9887
- @ungrouped_logical_and_expr = 0
9888
- @ungrouped_logical_or_expr = 0
9937
+ @enclosure_expr_stack = [expression]
9938
+ @multiplicative_exprs = Hash.new(0)
9939
+ @additive_exprs = Hash.new(0)
9940
+ @shift_exprs = Hash.new(0)
9941
+ @relational_exprs = Hash.new(0)
9942
+ @equality_exprs = Hash.new(0)
9943
+ @and_exprs = Hash.new(0)
9944
+ @xor_exprs = Hash.new(0)
9945
+ @or_exprs = Hash.new(0)
9946
+ @logical_and_exprs = Hash.new(0)
9947
+ @logical_or_exprs = Hash.new(0)
9889
9948
  end
9890
9949
 
9891
9950
  def execute
@@ -9893,134 +9952,157 @@ module CBuiltin #:nodoc:
9893
9952
  end
9894
9953
 
9895
9954
  def visit_grouped_expression(node)
9896
- @group_depth += 1
9955
+ @enclosure_expr_stack.push(node)
9897
9956
  super
9898
- @group_depth -= 1
9957
+ @enclosure_expr_stack.pop
9958
+ end
9959
+
9960
+ def visit_array_subscript_expression(node)
9961
+ AmbiguousExpressionDetector.new(@context, node.array_subscript).execute
9962
+ end
9963
+
9964
+ def visit_function_call_expression(node)
9965
+ node.argument_expressions.each do |expr|
9966
+ AmbiguousExpressionDetector.new(@context, expr).execute
9967
+ end
9899
9968
  end
9900
9969
 
9901
9970
  def visit_multiplicative_expression(node)
9902
9971
  super
9903
- @ungrouped_multiplicative_expr += 1 if @group_depth == 0
9972
+ @multiplicative_exprs[current_enclosure_expr] += 1
9904
9973
  end
9905
9974
 
9906
9975
  def visit_additive_expression(node)
9907
9976
  super
9908
- @ungrouped_additive_expr += 1 if @group_depth == 0
9977
+ @additive_exprs[current_enclosure_expr] += 1
9909
9978
  end
9910
9979
 
9911
9980
  def visit_shift_expression(node)
9912
9981
  super
9913
- @ungrouped_shift_expr += 1 if @group_depth == 0
9914
-
9915
- unless @already_warned
9916
- if @ungrouped_multiplicative_expr + @ungrouped_additive_expr > 0
9917
- W(:W0502, @expression.head_location)
9918
- @already_warned = true
9919
- end
9982
+ @shift_exprs[current_enclosure_expr] += 1
9983
+ if current_multiplicative_exprs + current_additive_exprs > 0
9984
+ W(:W0502, current_enclosure_expr.head_location)
9920
9985
  end
9921
9986
  end
9922
9987
 
9923
9988
  def visit_relational_expression(node)
9924
9989
  super
9925
- @ungrouped_relational_expr += 1 if @group_depth == 0
9926
-
9927
- unless @already_warned
9928
- if @ungrouped_multiplicative_expr + @ungrouped_additive_expr +
9929
- @ungrouped_shift_expr > 0
9930
- W(:W0502, @expression.head_location)
9931
- @already_warned = true
9932
- end
9990
+ @relational_exprs[current_enclosure_expr] += 1
9991
+ if current_multiplicative_exprs + current_additive_exprs +
9992
+ current_shift_exprs > 0
9993
+ W(:W0502, current_enclosure_expr.head_location)
9933
9994
  end
9934
9995
  end
9935
9996
 
9936
9997
  def visit_equality_expression(node)
9937
9998
  super
9938
- @ungrouped_equality_expr += 1 if @group_depth == 0
9939
-
9940
- unless @already_warned
9941
- if @ungrouped_multiplicative_expr + @ungrouped_additive_expr +
9942
- @ungrouped_shift_expr + @ungrouped_relational_expr > 0
9943
- W(:W0502, @expression.head_location)
9944
- @already_warned = true
9945
- end
9999
+ @equality_exprs[current_enclosure_expr] += 1
10000
+ if current_multiplicative_exprs + current_additive_exprs +
10001
+ current_shift_exprs + current_relational_exprs > 0
10002
+ W(:W0502, current_enclosure_expr.head_location)
9946
10003
  end
9947
10004
  end
9948
10005
 
9949
10006
  def visit_and_expression(node)
9950
10007
  super
9951
- @ungrouped_and_expr += 1 if @group_depth == 0
9952
-
9953
- unless @already_warned
9954
- if @ungrouped_multiplicative_expr + @ungrouped_additive_expr +
9955
- @ungrouped_shift_expr + @ungrouped_relational_expr +
9956
- @ungrouped_equality_expr > 0
9957
- W(:W0502, @expression.head_location)
9958
- @already_warned = true
9959
- end
10008
+ @and_exprs[current_enclosure_expr] += 1
10009
+ if current_multiplicative_exprs + current_additive_exprs +
10010
+ current_shift_exprs + current_relational_exprs +
10011
+ current_equality_exprs > 0
10012
+ W(:W0502, current_enclosure_expr.head_location)
9960
10013
  end
9961
10014
  end
9962
10015
 
9963
10016
  def visit_exclusive_or_expression(node)
9964
10017
  super
9965
- @ungrouped_xor_expr += 1 if @group_depth == 0
9966
-
9967
- unless @already_warned
9968
- if @ungrouped_multiplicative_expr + @ungrouped_additive_expr +
9969
- @ungrouped_shift_expr + @ungrouped_relational_expr +
9970
- @ungrouped_equality_expr + @ungrouped_and_expr > 0
9971
- W(:W0502, @expression.head_location)
9972
- @already_warned = true
9973
- end
10018
+ @xor_exprs[current_enclosure_expr] += 1
10019
+ if current_multiplicative_exprs + current_additive_exprs +
10020
+ current_shift_exprs + current_relational_exprs +
10021
+ current_equality_exprs + current_and_exprs > 0
10022
+ W(:W0502, current_enclosure_expr.head_location)
9974
10023
  end
9975
10024
  end
9976
10025
 
9977
10026
  def visit_inclusive_or_expression(node)
9978
10027
  super
9979
- @ungrouped_or_expr += 1 if @group_depth == 0
9980
-
9981
- unless @already_warned
9982
- if @ungrouped_multiplicative_expr + @ungrouped_additive_expr +
9983
- @ungrouped_shift_expr + @ungrouped_relational_expr +
9984
- @ungrouped_equality_expr + @ungrouped_and_expr +
9985
- @ungrouped_xor_expr > 0
9986
- W(:W0502, @expression.head_location)
9987
- @already_warned = true
9988
- end
10028
+ @or_exprs[current_enclosure_expr] += 1
10029
+ if current_multiplicative_exprs + current_additive_exprs +
10030
+ current_shift_exprs + current_relational_exprs +
10031
+ current_equality_exprs + current_and_exprs + current_xor_exprs > 0
10032
+ W(:W0502, current_enclosure_expr.head_location)
9989
10033
  end
9990
10034
  end
9991
10035
 
9992
10036
  def visit_logical_and_expression(node)
9993
10037
  super
9994
- @ungrouped_logical_and_expr += 1 if @group_depth == 0
9995
-
9996
- unless @already_warned
9997
- if @ungrouped_multiplicative_expr + @ungrouped_additive_expr +
9998
- @ungrouped_shift_expr + @ungrouped_relational_expr +
9999
- @ungrouped_equality_expr + @ungrouped_and_expr +
10000
- @ungrouped_xor_expr + @ungrouped_or_expr > 0
10001
- W(:W0502, @expression.head_location)
10002
- @already_warned = true
10003
- end
10038
+ @logical_and_exprs[current_enclosure_expr] += 1
10039
+ if current_multiplicative_exprs + current_additive_exprs +
10040
+ current_shift_exprs + current_relational_exprs +
10041
+ current_equality_exprs + current_and_exprs +
10042
+ current_xor_exprs + current_or_exprs > 0
10043
+ W(:W0502, current_enclosure_expr.head_location)
10004
10044
  end
10005
10045
  end
10006
10046
 
10007
10047
  def visit_logical_or_expression(node)
10008
10048
  super
10009
- @ungrouped_logical_or_expr += 1 if @group_depth == 0
10010
-
10011
- unless @already_warned
10012
- if @ungrouped_multiplicative_expr + @ungrouped_additive_expr +
10013
- @ungrouped_shift_expr + @ungrouped_relational_expr +
10014
- @ungrouped_equality_expr + @ungrouped_and_expr +
10015
- @ungrouped_xor_expr + @ungrouped_or_expr +
10016
- @ungrouped_logical_and_expr > 0
10017
- W(:W0502, @expression.head_location)
10018
- @already_warned = true
10019
- end
10049
+ @logical_or_exprs[current_enclosure_expr] += 1
10050
+ if current_multiplicative_exprs + current_additive_exprs +
10051
+ current_shift_exprs + current_relational_exprs +
10052
+ current_equality_exprs + current_and_exprs +
10053
+ current_xor_exprs + current_or_exprs +
10054
+ current_logical_and_exprs > 0
10055
+ W(:W0502, current_enclosure_expr.head_location)
10020
10056
  end
10021
10057
  end
10022
10058
 
10059
+ def visit_conditional_expression(node)
10060
+ AmbiguousExpressionDetector.new(@context, node.condition).execute
10061
+ AmbiguousExpressionDetector.new(@context, node.then_expression).execute
10062
+ AmbiguousExpressionDetector.new(@context, node.else_expression).execute
10063
+ end
10064
+
10023
10065
  private
10066
+ def current_multiplicative_exprs
10067
+ @multiplicative_exprs[current_enclosure_expr]
10068
+ end
10069
+
10070
+ def current_additive_exprs
10071
+ @additive_exprs[current_enclosure_expr]
10072
+ end
10073
+
10074
+ def current_shift_exprs
10075
+ @shift_exprs[current_enclosure_expr]
10076
+ end
10077
+
10078
+ def current_relational_exprs
10079
+ @relational_exprs[current_enclosure_expr]
10080
+ end
10081
+
10082
+ def current_equality_exprs
10083
+ @equality_exprs[current_enclosure_expr]
10084
+ end
10085
+
10086
+ def current_and_exprs
10087
+ @and_exprs[current_enclosure_expr]
10088
+ end
10089
+
10090
+ def current_xor_exprs
10091
+ @xor_exprs[current_enclosure_expr]
10092
+ end
10093
+
10094
+ def current_or_exprs
10095
+ @or_exprs[current_enclosure_expr]
10096
+ end
10097
+
10098
+ def current_logical_and_exprs
10099
+ @logical_and_exprs[current_enclosure_expr]
10100
+ end
10101
+
10102
+ def current_enclosure_expr
10103
+ @enclosure_expr_stack.last
10104
+ end
10105
+
10024
10106
  def report
10025
10107
  @context.report
10026
10108
  end