adlint 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (465) hide show
  1. data/AUTHORS +27 -0
  2. data/COPYING +674 -0
  3. data/ChangeLog +820 -0
  4. data/INSTALL +78 -0
  5. data/MANIFEST +464 -0
  6. data/NEWS +38 -0
  7. data/README +74 -0
  8. data/Rakefile +167 -0
  9. data/TODO +29 -0
  10. data/bin/adlint +141 -0
  11. data/bin/adlint_chk +129 -0
  12. data/bin/adlint_cma +122 -0
  13. data/bin/adlint_sma +129 -0
  14. data/bin/adlintize +286 -0
  15. data/etc/conf.d/fallback/cinit.erb +11 -0
  16. data/etc/conf.d/fallback/traits.erb +216 -0
  17. data/etc/conf.d/i686-cygwin/cinit-gcc_4.3.4.erb +149 -0
  18. data/etc/conf.d/i686-cygwin/traits-gcc_4.3.4.erb +227 -0
  19. data/etc/conf.d/i686-devkit/cinit-gcc_4.5.2.erb +224 -0
  20. data/etc/conf.d/i686-devkit/traits-gcc_4.5.2.erb +226 -0
  21. data/etc/conf.d/i686-linux/cinit-gcc_4.5.1.erb +219 -0
  22. data/etc/conf.d/i686-linux/traits-gcc_4.5.1.erb +224 -0
  23. data/etc/conf.d/i686-mingw/cinit-gcc_4.6.1.erb +234 -0
  24. data/etc/conf.d/i686-mingw/traits-gcc_4.6.1.erb +226 -0
  25. data/etc/conf.d/noarch/GNUmakefile.erb +119 -0
  26. data/etc/conf.d/noarch/adlint_all_bat.erb +9 -0
  27. data/etc/conf.d/noarch/adlint_all_sh.erb +10 -0
  28. data/etc/conf.d/noarch/pinit.erb +11 -0
  29. data/etc/mesg.d/en_US/messages.yml +784 -0
  30. data/etc/mesg.d/ja_JP/messages.yml +784 -0
  31. data/lib/adlint/analyzer.rb +294 -0
  32. data/lib/adlint/c/branch.rb +251 -0
  33. data/lib/adlint/c/builtin.rb +92 -0
  34. data/lib/adlint/c/code.rb +490 -0
  35. data/lib/adlint/c/const.rb +465 -0
  36. data/lib/adlint/c/conv.rb +212 -0
  37. data/lib/adlint/c/ctrlexpr.rb +949 -0
  38. data/lib/adlint/c/domain.rb +7499 -0
  39. data/lib/adlint/c/environ.rb +133 -0
  40. data/lib/adlint/c/expr.rb +1725 -0
  41. data/lib/adlint/c/format.rb +3209 -0
  42. data/lib/adlint/c/interp.rb +1740 -0
  43. data/lib/adlint/c/lexer.rb +241 -0
  44. data/lib/adlint/c/mediator.rb +313 -0
  45. data/lib/adlint/c/message.rb +13597 -0
  46. data/lib/adlint/c/metric.rb +765 -0
  47. data/lib/adlint/c/object.rb +1018 -0
  48. data/lib/adlint/c/parser.rb +3800 -0
  49. data/lib/adlint/c/parser.y +2054 -0
  50. data/lib/adlint/c/phase.rb +712 -0
  51. data/lib/adlint/c/resolver.rb +270 -0
  52. data/lib/adlint/c/scanner.rb +248 -0
  53. data/lib/adlint/c/scope.rb +74 -0
  54. data/lib/adlint/c/syntax.rb +4279 -0
  55. data/lib/adlint/c/type.rb +7506 -0
  56. data/lib/adlint/c/util.rb +91 -0
  57. data/lib/adlint/c/value.rb +2310 -0
  58. data/lib/adlint/c.rb +56 -0
  59. data/lib/adlint/code.rb +500 -0
  60. data/lib/adlint/cpp/code.rb +189 -0
  61. data/lib/adlint/cpp/constexpr.rb +721 -0
  62. data/lib/adlint/cpp/constexpr.y +389 -0
  63. data/lib/adlint/cpp/eval.rb +1012 -0
  64. data/lib/adlint/cpp/lexer.rb +860 -0
  65. data/lib/adlint/cpp/macro.rb +637 -0
  66. data/lib/adlint/cpp/message.rb +992 -0
  67. data/lib/adlint/cpp/phase.rb +176 -0
  68. data/lib/adlint/cpp/scanner.rb +93 -0
  69. data/lib/adlint/cpp/source.rb +169 -0
  70. data/lib/adlint/cpp/subst.rb +300 -0
  71. data/lib/adlint/cpp/syntax.rb +1412 -0
  72. data/lib/adlint/cpp/util.rb +97 -0
  73. data/lib/adlint/cpp.rb +43 -0
  74. data/lib/adlint/driver.rb +147 -0
  75. data/lib/adlint/error.rb +179 -0
  76. data/lib/adlint/lang.rb +97 -0
  77. data/lib/adlint/ld/message.rb +259 -0
  78. data/lib/adlint/ld/metric.rb +57 -0
  79. data/lib/adlint/ld/object.rb +542 -0
  80. data/lib/adlint/ld/phase.rb +193 -0
  81. data/lib/adlint/ld/typedef.rb +109 -0
  82. data/lib/adlint/ld/util.rb +88 -0
  83. data/lib/adlint/ld.rb +37 -0
  84. data/lib/adlint/lexer.rb +293 -0
  85. data/lib/adlint/message.rb +368 -0
  86. data/lib/adlint/metric.rb +805 -0
  87. data/lib/adlint/monitor.rb +144 -0
  88. data/lib/adlint/phase.rb +90 -0
  89. data/lib/adlint/prelude.rb +314 -0
  90. data/lib/adlint/report.rb +617 -0
  91. data/lib/adlint/source.rb +155 -0
  92. data/lib/adlint/symbol.rb +127 -0
  93. data/lib/adlint/token.rb +215 -0
  94. data/lib/adlint/traits.rb +643 -0
  95. data/lib/adlint/util.rb +524 -0
  96. data/lib/adlint/version.rb +71 -0
  97. data/lib/adlint.rb +66 -0
  98. data/share/HEADER +45 -0
  99. data/share/demo/Makefile +110 -0
  100. data/share/demo/ambig_operator/ambig_operator.c +289 -0
  101. data/share/demo/arg_points_unset/arg_points_unset.c +37 -0
  102. data/share/demo/array_range/array_range.c +62 -0
  103. data/share/demo/bad_bitfields/bad_bitfields.c +74 -0
  104. data/share/demo/bad_brace/bad_brace.c +19 -0
  105. data/share/demo/bad_charset/abcde$.h +0 -0
  106. data/share/demo/bad_charset/bad_charset.c +22 -0
  107. data/share/demo/bad_comment/bad_comment.c +3 -0
  108. data/share/demo/bad_const/bad_const.c +19 -0
  109. data/share/demo/bad_conv/bad_conv.c +48 -0
  110. data/share/demo/bad_indent/bad_indent.c +50 -0
  111. data/share/demo/bad_init/bad_init.c +49 -0
  112. data/share/demo/bad_macro/bad_macro.c +97 -0
  113. data/share/demo/bitwise_expr/bitwise_expr.c +19 -0
  114. data/share/demo/call_by_value/call_by_value.c +26 -0
  115. data/share/demo/cross_ref/cross_ref.c +21 -0
  116. data/share/demo/dangling_else/dangling_else.c +20 -0
  117. data/share/demo/dead_code/dead_code.c +237 -0
  118. data/share/demo/deep_nest/deep_nest.c +57 -0
  119. data/share/demo/dense_switch/dense_switch.c +62 -0
  120. data/share/demo/direct_recur/direct_recur.c +15 -0
  121. data/share/demo/div_by_zero/div_by_zero.c +35 -0
  122. data/share/demo/dos_source/dos_source.c +7 -0
  123. data/share/demo/funptr_cast/funptr_cast.c +26 -0
  124. data/share/demo/goto_stmt/goto_stmt.c +19 -0
  125. data/share/demo/id_hiding/id_hiding.c +19 -0
  126. data/share/demo/ill_defined/ill_defined.c +13 -0
  127. data/share/demo/implicit_conv/implicit_conv.c +60 -0
  128. data/share/demo/implicit_int/implicit_int.c +14 -0
  129. data/share/demo/incomplete_type/incomplete_type.c +49 -0
  130. data/share/demo/indirect_recur/indirect_recur_1.c +14 -0
  131. data/share/demo/indirect_recur/indirect_recur_1.h +7 -0
  132. data/share/demo/indirect_recur/indirect_recur_2.c +12 -0
  133. data/share/demo/indirect_recur/indirect_recur_2.h +6 -0
  134. data/share/demo/indirect_recur/indirect_recur_3.c +6 -0
  135. data/share/demo/indirect_recur/indirect_recur_3.h +6 -0
  136. data/share/demo/indirect_recur/indirect_recur_4.c +25 -0
  137. data/share/demo/intro_demo/intro_demo.c +76 -0
  138. data/share/demo/intro_demo/intro_demo.h +12 -0
  139. data/share/demo/intro_demo/useless_header.h +5 -0
  140. data/share/demo/invalid_call/invalid_call.c +32 -0
  141. data/share/demo/kandr_fundef/kandr_fundef.c +10 -0
  142. data/share/demo/line_comment/line_comment.c +12 -0
  143. data/share/demo/local_decl/local_decl.c +9 -0
  144. data/share/demo/logical_trick/logical_trick.c +36 -0
  145. data/share/demo/long_sym/long_sym.c +5 -0
  146. data/share/demo/loop_var/loop_var.c +92 -0
  147. data/share/demo/malloc_or_die/malloc_or_die.c +43 -0
  148. data/share/demo/may_be_null/may_be_null.c +52 -0
  149. data/share/demo/may_be_null_arith/may_be_null_arith.c +15 -0
  150. data/share/demo/may_be_unset/may_be_unset.c +34 -0
  151. data/share/demo/mmapped_io/mmapped_io.c +23 -0
  152. data/share/demo/multi_break/multi_break.c +33 -0
  153. data/share/demo/multi_decl/multi_decl_1.c +17 -0
  154. data/share/demo/multi_decl/multi_decl_1.h +6 -0
  155. data/share/demo/multi_decl/multi_decl_2.c +13 -0
  156. data/share/demo/multi_decl/multi_decl_2.h +6 -0
  157. data/share/demo/multi_decl/multi_decl_3.c +22 -0
  158. data/share/demo/multi_def/multi_def_1.c +36 -0
  159. data/share/demo/multi_def/multi_def_1.h +6 -0
  160. data/share/demo/multi_def/multi_def_2.c +22 -0
  161. data/share/demo/multi_def/multi_def_2.h +6 -0
  162. data/share/demo/multi_def/multi_def_3.c +6 -0
  163. data/share/demo/multi_typedef/multi_typedef.c +11 -0
  164. data/share/demo/multi_typedef/multi_typedef_1.h +1 -0
  165. data/share/demo/multi_typedef/multi_typedef_2.h +1 -0
  166. data/share/demo/must_be_false/must_be_false.c +53 -0
  167. data/share/demo/must_be_null/must_be_null.c +13 -0
  168. data/share/demo/must_be_null_arith/must_be_null_arith.c +14 -0
  169. data/share/demo/must_be_true/must_be_true.c +21 -0
  170. data/share/demo/no_eof_nl/no_eof_nl.c +4 -0
  171. data/share/demo/no_void_arg/no_void_arg.c +14 -0
  172. data/share/demo/null_stmt/null_stmt.c +19 -0
  173. data/share/demo/octal_const/octal_const.c +20 -0
  174. data/share/demo/output_by_param/output_by_param.c +17 -0
  175. data/share/demo/overflow/overflow.c +74 -0
  176. data/share/demo/press_release/press_release.c +40 -0
  177. data/share/demo/retn_lvar_addr/retn_lvar_addr.c +47 -0
  178. data/share/demo/shift_expr/shift_expr.c +14 -0
  179. data/share/demo/should_be_typedef/should_be_typedef.c +51 -0
  180. data/share/demo/static_paths/static_paths.c +153 -0
  181. data/share/demo/static_vars/static_vars.c +39 -0
  182. data/share/demo/tag_hiding/tag_hiding.c +18 -0
  183. data/share/demo/tricky_incdec/tricky_incdec.c +12 -0
  184. data/share/demo/undefined_macro/undefined_macro.c +17 -0
  185. data/share/demo/uninit_vars/uninit_vars.c +28 -0
  186. data/share/demo/union_type/union_type.c +23 -0
  187. data/share/demo/unmatch_decl/unmatch_decl_1.c +12 -0
  188. data/share/demo/unmatch_decl/unmatch_decl_1.h +8 -0
  189. data/share/demo/unmatch_decl/unmatch_decl_2.c +10 -0
  190. data/share/demo/unmatch_decl/unmatch_decl_2.h +8 -0
  191. data/share/demo/unmatch_decl/unmatch_decl_3.c +7 -0
  192. data/share/demo/unmatch_paren_macro/unmatch_paren_macro.c +15 -0
  193. data/share/demo/unreachable/unreachable.c +34 -0
  194. data/share/demo/useless_exp_funs/useless_exp_funs_1.c +14 -0
  195. data/share/demo/useless_exp_funs/useless_exp_funs_1.h +1 -0
  196. data/share/demo/useless_exp_funs/useless_exp_funs_2.c +6 -0
  197. data/share/demo/useless_exp_vars/useless_export_1.c +8 -0
  198. data/share/demo/useless_exp_vars/useless_export_1.h +1 -0
  199. data/share/demo/useless_exp_vars/useless_export_2.c +7 -0
  200. data/share/demo/useless_expr/useless_expr.c +17 -0
  201. data/share/demo/useless_funs/useless_funs_1.c +21 -0
  202. data/share/demo/useless_funs/useless_funs_1.h +8 -0
  203. data/share/demo/useless_funs/useless_funs_2.c +6 -0
  204. data/share/demo/useless_header/useless_header.c +9 -0
  205. data/share/demo/useless_header/useless_header_1.h +12 -0
  206. data/share/demo/useless_header/useless_header_2.h +6 -0
  207. data/share/demo/useless_header/useless_header_3.h +9 -0
  208. data/share/demo/useless_header/useless_header_4.h +3 -0
  209. data/share/demo/useless_vars/useless_vars.c +17 -0
  210. data/share/demo/va_funcall/va_funcall.c +25 -0
  211. data/share/demo/various_fundef/various_fundef.c +36 -0
  212. data/share/demo/wchar_wstring/wchar_wstring.c +7 -0
  213. data/share/demo/wrap_around/wrap_around.c +38 -0
  214. data/share/doc/Makefile +16 -0
  215. data/share/doc/adlint_on_adqua.png +0 -0
  216. data/share/doc/adlint_on_eclipse_en.png +0 -0
  217. data/share/doc/adlint_on_eclipse_ja.png +0 -0
  218. data/share/doc/adlint_on_vim_en.png +0 -0
  219. data/share/doc/adlint_on_vim_ja.png +0 -0
  220. data/share/doc/developers_guide_ja.html +171 -0
  221. data/share/doc/developers_guide_ja.texi +87 -0
  222. data/share/doc/gen_mesg_sections.rb +39 -0
  223. data/share/doc/samples/GNUmakefile +162 -0
  224. data/share/doc/samples/adlint_traits.yml +238 -0
  225. data/share/doc/texinfo.css +22 -0
  226. data/share/doc/users_guide_en.html +39975 -0
  227. data/share/doc/users_guide_en.texi +32640 -0
  228. data/share/doc/users_guide_ja.html +40505 -0
  229. data/share/doc/users_guide_ja.texi +33189 -0
  230. data/share/logo/adlint-110.png +0 -0
  231. data/share/logo/adlint-524.png +0 -0
  232. data/share/logo/adlint.svg +4637 -0
  233. data/share/sample/README +6 -0
  234. data/share/sample/bison-2.5/adlint/GNUmakefile +170 -0
  235. data/share/sample/bison-2.5/adlint/adlint_traits.yml +225 -0
  236. data/share/sample/bison-2.5/adlint/lib/GNUmakefile +198 -0
  237. data/share/sample/bison-2.5/adlint/lib/adlint_cinit.h +228 -0
  238. data/share/sample/bison-2.5/adlint/lib/adlint_pinit.h +21 -0
  239. data/share/sample/bison-2.5/adlint/lib/adlint_traits.yml +238 -0
  240. data/share/sample/bison-2.5/adlint/src/GNUmakefile +166 -0
  241. data/share/sample/bison-2.5/adlint/src/adlint_cinit.h +228 -0
  242. data/share/sample/bison-2.5/adlint/src/adlint_pinit.h +21 -0
  243. data/share/sample/bison-2.5/adlint/src/adlint_traits.yml +239 -0
  244. data/share/sample/ctags-5.8/adlint/GNUmakefile +169 -0
  245. data/share/sample/ctags-5.8/adlint/adlint_cinit.h +219 -0
  246. data/share/sample/ctags-5.8/adlint/adlint_pinit.h +13 -0
  247. data/share/sample/ctags-5.8/adlint/adlint_traits.yml +225 -0
  248. data/share/sample/flex-2.5.35/adlint/GNUmakefile +140 -0
  249. data/share/sample/flex-2.5.35/adlint/adlint_cinit.h +219 -0
  250. data/share/sample/flex-2.5.35/adlint/adlint_pinit.h +14 -0
  251. data/share/sample/flex-2.5.35/adlint/adlint_traits.yml +225 -0
  252. data/share/sample/ruby-1.9.3-p0/adlint/GNUmakefile +314 -0
  253. data/share/sample/ruby-1.9.3-p0/adlint/adlint_traits.yml +225 -0
  254. data/share/sample/ruby-1.9.3-p0/adlint/core/GNUmakefile +204 -0
  255. data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_cinit.h +228 -0
  256. data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_pinit.h +28 -0
  257. data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_traits.yml +240 -0
  258. data/share/sample/ruby-1.9.3-p0/adlint/enc/GNUmakefile +163 -0
  259. data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_cinit.h +228 -0
  260. data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_pinit.h +24 -0
  261. data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_traits.yml +240 -0
  262. data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/GNUmakefile +149 -0
  263. data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_cinit.h +228 -0
  264. data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_pinit.h +24 -0
  265. data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_traits.yml +240 -0
  266. data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/GNUmakefile +131 -0
  267. data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_cinit.h +228 -0
  268. data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_pinit.h +24 -0
  269. data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_traits.yml +241 -0
  270. data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/GNUmakefile +131 -0
  271. data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_cinit.h +228 -0
  272. data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_pinit.h +24 -0
  273. data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_traits.yml +241 -0
  274. data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/GNUmakefile +131 -0
  275. data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_cinit.h +228 -0
  276. data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_pinit.h +24 -0
  277. data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_traits.yml +241 -0
  278. data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/GNUmakefile +131 -0
  279. data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_cinit.h +228 -0
  280. data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_pinit.h +24 -0
  281. data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_traits.yml +241 -0
  282. data/share/sample/ruby-1.9.3-p0/adlint/ext-date/GNUmakefile +134 -0
  283. data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_cinit.h +228 -0
  284. data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_pinit.h +24 -0
  285. data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_traits.yml +241 -0
  286. data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/GNUmakefile +131 -0
  287. data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_cinit.h +228 -0
  288. data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_pinit.h +24 -0
  289. data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_traits.yml +241 -0
  290. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/GNUmakefile +131 -0
  291. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_cinit.h +228 -0
  292. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_pinit.h +24 -0
  293. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_traits.yml +241 -0
  294. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/GNUmakefile +131 -0
  295. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_cinit.h +228 -0
  296. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_pinit.h +24 -0
  297. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_traits.yml +242 -0
  298. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/GNUmakefile +132 -0
  299. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_cinit.h +228 -0
  300. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_pinit.h +24 -0
  301. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_traits.yml +242 -0
  302. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/GNUmakefile +132 -0
  303. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_cinit.h +228 -0
  304. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_pinit.h +24 -0
  305. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_traits.yml +242 -0
  306. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/GNUmakefile +132 -0
  307. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_cinit.h +228 -0
  308. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_pinit.h +24 -0
  309. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_traits.yml +242 -0
  310. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/GNUmakefile +132 -0
  311. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_cinit.h +228 -0
  312. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_pinit.h +24 -0
  313. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_traits.yml +242 -0
  314. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/GNUmakefile +134 -0
  315. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_cinit.h +228 -0
  316. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_pinit.h +24 -0
  317. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_traits.yml +241 -0
  318. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/GNUmakefile +140 -0
  319. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_cinit.h +228 -0
  320. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_pinit.h +24 -0
  321. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_traits.yml +242 -0
  322. data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/GNUmakefile +131 -0
  323. data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_cinit.h +228 -0
  324. data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_pinit.h +24 -0
  325. data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_traits.yml +241 -0
  326. data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/GNUmakefile +131 -0
  327. data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_cinit.h +228 -0
  328. data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_pinit.h +24 -0
  329. data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_traits.yml +241 -0
  330. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/GNUmakefile +131 -0
  331. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_cinit.h +228 -0
  332. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_pinit.h +24 -0
  333. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_traits.yml +241 -0
  334. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/GNUmakefile +134 -0
  335. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_cinit.h +228 -0
  336. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_pinit.h +24 -0
  337. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_traits.yml +242 -0
  338. data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/GNUmakefile +131 -0
  339. data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_cinit.h +228 -0
  340. data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_pinit.h +24 -0
  341. data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_traits.yml +241 -0
  342. data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/GNUmakefile +131 -0
  343. data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_cinit.h +228 -0
  344. data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_pinit.h +24 -0
  345. data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_traits.yml +241 -0
  346. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/GNUmakefile +131 -0
  347. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_cinit.h +228 -0
  348. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_pinit.h +24 -0
  349. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_traits.yml +241 -0
  350. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/GNUmakefile +131 -0
  351. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_cinit.h +228 -0
  352. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_pinit.h +24 -0
  353. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_traits.yml +241 -0
  354. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/GNUmakefile +131 -0
  355. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_cinit.h +228 -0
  356. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_pinit.h +24 -0
  357. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_traits.yml +241 -0
  358. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/GNUmakefile +131 -0
  359. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_cinit.h +228 -0
  360. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_pinit.h +24 -0
  361. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_traits.yml +241 -0
  362. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/GNUmakefile +131 -0
  363. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_cinit.h +228 -0
  364. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_pinit.h +24 -0
  365. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_traits.yml +241 -0
  366. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/GNUmakefile +131 -0
  367. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_cinit.h +228 -0
  368. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_pinit.h +24 -0
  369. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_traits.yml +241 -0
  370. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/GNUmakefile +131 -0
  371. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_cinit.h +228 -0
  372. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_pinit.h +24 -0
  373. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_traits.yml +241 -0
  374. data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/GNUmakefile +131 -0
  375. data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_cinit.h +228 -0
  376. data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_pinit.h +24 -0
  377. data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_traits.yml +241 -0
  378. data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/GNUmakefile +162 -0
  379. data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_cinit.h +228 -0
  380. data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_pinit.h +24 -0
  381. data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_traits.yml +241 -0
  382. data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/GNUmakefile +131 -0
  383. data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_cinit.h +228 -0
  384. data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_pinit.h +24 -0
  385. data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_traits.yml +241 -0
  386. data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/GNUmakefile +135 -0
  387. data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_cinit.h +228 -0
  388. data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_pinit.h +24 -0
  389. data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_traits.yml +241 -0
  390. data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/GNUmakefile +131 -0
  391. data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_cinit.h +228 -0
  392. data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_pinit.h +24 -0
  393. data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_traits.yml +241 -0
  394. data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/GNUmakefile +131 -0
  395. data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_cinit.h +228 -0
  396. data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_pinit.h +24 -0
  397. data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_traits.yml +241 -0
  398. data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/GNUmakefile +131 -0
  399. data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_cinit.h +228 -0
  400. data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_pinit.h +24 -0
  401. data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_traits.yml +241 -0
  402. data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/GNUmakefile +131 -0
  403. data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_cinit.h +228 -0
  404. data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_pinit.h +24 -0
  405. data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_traits.yml +241 -0
  406. data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/GNUmakefile +132 -0
  407. data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_cinit.h +228 -0
  408. data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_pinit.h +24 -0
  409. data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_traits.yml +241 -0
  410. data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/GNUmakefile +144 -0
  411. data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_cinit.h +228 -0
  412. data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_pinit.h +24 -0
  413. data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_traits.yml +241 -0
  414. data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/GNUmakefile +131 -0
  415. data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_cinit.h +228 -0
  416. data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_pinit.h +24 -0
  417. data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_traits.yml +241 -0
  418. data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/GNUmakefile +131 -0
  419. data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_cinit.h +228 -0
  420. data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_pinit.h +24 -0
  421. data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_traits.yml +241 -0
  422. data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/GNUmakefile +140 -0
  423. data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_cinit.h +228 -0
  424. data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_pinit.h +24 -0
  425. data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_traits.yml +241 -0
  426. data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/GNUmakefile +131 -0
  427. data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_cinit.h +228 -0
  428. data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_pinit.h +24 -0
  429. data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_traits.yml +241 -0
  430. data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/GNUmakefile +131 -0
  431. data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_cinit.h +228 -0
  432. data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_pinit.h +24 -0
  433. data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_traits.yml +241 -0
  434. data/share/sample/screen-4.0.3/adlint/GNUmakefile +162 -0
  435. data/share/sample/screen-4.0.3/adlint/adlint_cinit.h +228 -0
  436. data/share/sample/screen-4.0.3/adlint/adlint_pinit.h +21 -0
  437. data/share/sample/screen-4.0.3/adlint/adlint_traits.yml +238 -0
  438. data/share/sample/vim-7.3/adlint/vim/GNUmakefile +185 -0
  439. data/share/sample/vim-7.3/adlint/vim/adlint_cinit.h +228 -0
  440. data/share/sample/vim-7.3/adlint/vim/adlint_pinit.h +25 -0
  441. data/share/sample/vim-7.3/adlint/vim/adlint_traits.yml +250 -0
  442. data/share/sample/vim-7.3/adlint/xxd/GNUmakefile +131 -0
  443. data/share/sample/vim-7.3/adlint/xxd/adlint_cinit.h +228 -0
  444. data/share/sample/vim-7.3/adlint/xxd/adlint_pinit.h +24 -0
  445. data/share/sample/vim-7.3/adlint/xxd/adlint_traits.yml +237 -0
  446. data/share/sample/zsh-4.3.15/adlint/GNUmakefile +146 -0
  447. data/share/sample/zsh-4.3.15/adlint/adlint_traits.yml +225 -0
  448. data/share/sample/zsh-4.3.15/adlint/builtins/GNUmakefile +132 -0
  449. data/share/sample/zsh-4.3.15/adlint/builtins/adlint_cinit.h +228 -0
  450. data/share/sample/zsh-4.3.15/adlint/builtins/adlint_pinit.h +24 -0
  451. data/share/sample/zsh-4.3.15/adlint/builtins/adlint_traits.yml +240 -0
  452. data/share/sample/zsh-4.3.15/adlint/core/GNUmakefile +153 -0
  453. data/share/sample/zsh-4.3.15/adlint/core/adlint_cinit.h +228 -0
  454. data/share/sample/zsh-4.3.15/adlint/core/adlint_pinit.h +23 -0
  455. data/share/sample/zsh-4.3.15/adlint/core/adlint_traits.yml +239 -0
  456. data/share/sample/zsh-4.3.15/adlint/modules/GNUmakefile +147 -0
  457. data/share/sample/zsh-4.3.15/adlint/modules/adlint_cinit.h +228 -0
  458. data/share/sample/zsh-4.3.15/adlint/modules/adlint_pinit.h +24 -0
  459. data/share/sample/zsh-4.3.15/adlint/modules/adlint_traits.yml +240 -0
  460. data/share/sample/zsh-4.3.15/adlint/zle/GNUmakefile +144 -0
  461. data/share/sample/zsh-4.3.15/adlint/zle/adlint_cinit.h +228 -0
  462. data/share/sample/zsh-4.3.15/adlint/zle/adlint_pinit.h +24 -0
  463. data/share/sample/zsh-4.3.15/adlint/zle/adlint_traits.yml +239 -0
  464. data/spec/MUST_WRITE_SPECS_WITH_RSPEC +0 -0
  465. metadata +532 -0
@@ -0,0 +1,1725 @@
1
+ # C expression evaluator.
2
+ #
3
+ # Author:: Yutaka Yanoh <mailto:yanoh@users.sourceforge.net>
4
+ # Copyright:: Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
5
+ # License:: GPLv3+: GNU General Public License version 3 or later
6
+ #
7
+ # Owner:: Yutaka Yanoh <mailto:yanoh@users.sourceforge.net>
8
+
9
+ #--
10
+ # ___ ____ __ ___ _________
11
+ # / | / _ |/ / / / | / /__ __/ Source Code Static Analyzer
12
+ # / /| | / / / / / / / |/ / / / AdLint - Advanced Lint
13
+ # / __ |/ /_/ / /___/ / /| / / /
14
+ # /_/ |_|_____/_____/_/_/ |_/ /_/ Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
15
+ #
16
+ # This file is part of AdLint.
17
+ #
18
+ # AdLint is free software: you can redistribute it and/or modify it under the
19
+ # terms of the GNU General Public License as published by the Free Software
20
+ # Foundation, either version 3 of the License, or (at your option) any later
21
+ # version.
22
+ #
23
+ # AdLint is distributed in the hope that it will be useful, but WITHOUT ANY
24
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
25
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
26
+ #
27
+ # You should have received a copy of the GNU General Public License along with
28
+ # AdLint. If not, see <http://www.gnu.org/licenses/>.
29
+ #
30
+ #++
31
+
32
+ require "adlint/c/mediator"
33
+ require "adlint/c/const"
34
+ require "adlint/c/conv"
35
+
36
+ module AdLint #:nodoc:
37
+ module C #:nodoc:
38
+
39
+ module ExpressionUtil
40
+ # NOTE: Host class of this module must include InterpreterMediator,
41
+ # NotifierMediator and Conversion.
42
+
43
+ def execute_array_subscript_expression(node, object, subscript)
44
+ unless object.variable? && (object.type.array? || object.type.pointer?)
45
+ return temporary_variable
46
+ end
47
+
48
+ array_or_pointer = object
49
+
50
+ result_type = array_or_pointer.type.unqualify.base_type
51
+ result_type = pointer_type(result_type) if result_type.array?
52
+
53
+ unless subscript.variable? && subscript.value.scalar? &&
54
+ subscript.value.exist?
55
+ return temporary_variable(result_type)
56
+ end
57
+
58
+ case
59
+ when array_or_pointer.type.array?
60
+ array = array_or_pointer
61
+ when array_or_pointer.type.pointer?
62
+ if pointee = pointee_of(array_or_pointer)
63
+ if pointee.type.array?
64
+ array = pointee
65
+ end
66
+ end
67
+ end
68
+
69
+ # NOTE: An array subscript converted to `int' implicitly.
70
+ if subscript.type.same_as?(int_type)
71
+ int_subscript = subscript
72
+ else
73
+ if int_subscript = do_conversion(subscript, int_type)
74
+ notify_implicit_conv_performed(node.array_subscript,
75
+ subscript, int_subscript)
76
+ else
77
+ return temporary_variable(result_type)
78
+ end
79
+ end
80
+
81
+ # FIXME: Domain of the subscript may have multiple values.
82
+ subscript_value = int_subscript.value.unique_sample
83
+ if array and inner_variable = array.inner_variable_at(subscript_value)
84
+ notify_variable_referred(node, inner_variable)
85
+ unless variable_reassigning?
86
+ notify_variable_value_referred(node, inner_variable)
87
+ end
88
+ if inner_variable.type.array?
89
+ result = temporary_variable(result_type,
90
+ pointer_value_of(inner_variable))
91
+ else
92
+ result = inner_variable
93
+ end
94
+ else
95
+ result = temporary_variable(result_type)
96
+ end
97
+
98
+ notify_array_subscript_expr_evaled(node, array_or_pointer,
99
+ int_subscript, array, result)
100
+ result
101
+ end
102
+
103
+ def execute_function_call_expression(node, object, args)
104
+ if object.function?
105
+ function = object
106
+ else
107
+ if object.type.pointer? && object.type.unqualify.base_type.function?
108
+ if pointee = pointee_of(object) and pointee.function?
109
+ function = pointee
110
+ else
111
+ function_type = object.type.unqualify.base_type
112
+ function = define_anonymous_function(function_type)
113
+ end
114
+ else
115
+ return temporary_variable
116
+ end
117
+ end
118
+
119
+ result = function.call(interpreter, args)
120
+ unless function.builtin?
121
+ notify_function_call_expr_evaled(node, function,
122
+ args.map { |arg, expr| arg }, result)
123
+ end
124
+
125
+ result
126
+ end
127
+
128
+ def execute_member_access_by_value_expression(node, object)
129
+ unless object.variable? && object.type.composite?
130
+ return temporary_variable
131
+ end
132
+
133
+ variable = object
134
+ member_variable = variable.inner_variable_named(node.identifier.value)
135
+
136
+ # NOTE: `member_variable' is nil when this expression represents the
137
+ # direct member access extension.
138
+ notify_member_access_expr_evaled(node, variable, member_variable)
139
+
140
+ if member_variable
141
+ notify_variable_referred(node, member_variable)
142
+ unless variable_reassigning?
143
+ notify_variable_value_referred(node, member_variable)
144
+ end
145
+ if member_variable.type.array?
146
+ type = pointer_type(member_variable.type.base_type)
147
+ return temporary_variable(type, pointer_value_of(member_variable))
148
+ end
149
+ member_variable
150
+ else
151
+ temporary_variable
152
+ end
153
+ end
154
+
155
+ def execute_member_access_by_pointer_expression(node, object)
156
+ unqualified_type = object.type.unqualify
157
+
158
+ unless object.variable? && unqualified_type.pointer? &&
159
+ unqualified_type.base_type.composite?
160
+ return temporary_variable
161
+ end
162
+
163
+ pointer = object
164
+ if pointee = pointee_of(pointer)
165
+ if pointee.type.array?
166
+ if first_element = pointee.inner_variable_at(0)
167
+ pointee = first_element
168
+ else
169
+ pointee = temporary_variable(object.type.unqualify.base_type)
170
+ end
171
+ end
172
+ end
173
+
174
+ if variable_reassigning?
175
+ notify_variable_value_referred(node, pointer)
176
+ end
177
+
178
+ if pointee && pointee.type.composite?
179
+ member_variable = pointee.inner_variable_named(node.identifier.value)
180
+ else
181
+ member = unqualified_type.base_type.member_named(node.identifier.value)
182
+ member_variable = temporary_variable(member.type) if member
183
+ end
184
+
185
+ # NOTE: `member_variable' is nil when this expression represents the
186
+ # direct member access extension.
187
+ notify_member_access_expr_evaled(node, pointer, member_variable)
188
+
189
+ if member_variable
190
+ notify_variable_referred(node, member_variable)
191
+ unless variable_reassigning?
192
+ notify_variable_value_referred(node, member_variable)
193
+ end
194
+ if member_variable.type.array?
195
+ type = pointer_type(member_variable.type.base_type)
196
+ return temporary_variable(type, pointer_value_of(member_variable))
197
+ end
198
+ member_variable
199
+ else
200
+ temporary_variable
201
+ end
202
+ end
203
+
204
+ def execute_postfix_increment_expression(node, object)
205
+ if object.variable?
206
+ variable = object
207
+
208
+ if variable.type.scalar?
209
+ result = temporary_variable(variable.type, variable.value.dup)
210
+ if variable.value.scalar?
211
+ variable.assign!(variable.value + ScalarValue.of(1))
212
+ end
213
+ else
214
+ result = temporary_variable
215
+ end
216
+
217
+ notify_postfix_increment_expr_evaled(node, variable, result)
218
+ notify_variable_value_updated(node, variable)
219
+
220
+ result
221
+ else
222
+ temporary_variable
223
+ end
224
+ end
225
+
226
+ def execute_postfix_decrement_expression(node, object)
227
+ if object.variable?
228
+ variable = object
229
+
230
+ if variable.type.scalar?
231
+ result = temporary_variable(variable.type, variable.value.dup)
232
+ if variable.value.scalar?
233
+ variable.assign!(variable.value - ScalarValue.of(1))
234
+ end
235
+ else
236
+ result = temporary_variable
237
+ end
238
+
239
+ notify_postfix_decrement_expr_evaled(node, variable, result)
240
+ notify_variable_value_updated(node, variable)
241
+
242
+ result
243
+ else
244
+ temporary_variable
245
+ end
246
+ end
247
+
248
+ def execute_prefix_increment_expression(node, object)
249
+ if object.variable?
250
+ variable = object
251
+
252
+ if variable.type.scalar?
253
+ original_value = variable.value.dup
254
+ if variable.value.scalar?
255
+ variable.assign!(variable.value + ScalarValue.of(1))
256
+ end
257
+ else
258
+ original_value = variable.value.dup
259
+ end
260
+
261
+ notify_prefix_increment_expr_evaled(node, variable, original_value)
262
+ notify_variable_value_updated(node, variable)
263
+
264
+ variable
265
+ else
266
+ temporary_variable
267
+ end
268
+ end
269
+
270
+ def execute_prefix_decrement_expression(node, object)
271
+ if object.variable?
272
+ variable = object
273
+
274
+ if variable.type.scalar?
275
+ original_value = variable.value.dup
276
+ if variable.value.scalar?
277
+ variable.assign!(variable.value - ScalarValue.of(1))
278
+ end
279
+ else
280
+ original_value = variable.value.dup
281
+ end
282
+
283
+ notify_prefix_decrement_expr_evaled(node, variable, original_value)
284
+ notify_variable_value_updated(node, variable)
285
+
286
+ variable
287
+ else
288
+ temporary_variable
289
+ end
290
+ end
291
+
292
+ def execute_indirection_expression(node, object)
293
+ if object.variable?
294
+ variable = object
295
+
296
+ return temporary_variable unless variable.type.pointer?
297
+
298
+ pointer = object
299
+ unqualified_type = pointer.type.unqualify
300
+
301
+ pointee = pointee_of(pointer)
302
+ if variable_reassigning?
303
+ notify_variable_value_referred(node, pointer)
304
+ end
305
+
306
+ case
307
+ when pointee
308
+ if pointee.type.array?
309
+ if first_element = pointee.inner_variable_at(0)
310
+ pointee = first_element
311
+ else
312
+ pointee = temporary_variable(unqualified_type.base_type)
313
+ end
314
+ end
315
+
316
+ unless variable_reassigning?
317
+ notify_variable_value_referred(node, pointee) if pointee.variable?
318
+ end
319
+
320
+ unless unqualified_type.base_type.same_as?(pointee.type)
321
+ pointee =
322
+ do_conversion(pointee, unqualified_type.base_type) ||
323
+ temporary_variable(unqualified_type.base_type)
324
+ end
325
+ when unqualified_type.base_type.function?
326
+ pointee = define_anonymous_function(unqualified_type.base_type)
327
+ else
328
+ pointee = temporary_variable(unqualified_type.base_type)
329
+ end
330
+
331
+ notify_indirection_expr_evaled(node, variable, pointee)
332
+ return pointee
333
+ end
334
+
335
+ temporary_variable
336
+ end
337
+
338
+ def execute_unary_arithmetic_expression(node, object)
339
+ if object.variable? && object.type.scalar?
340
+ variable = object
341
+
342
+ if variable.value.scalar?
343
+ case node.operator.type
344
+ when "+"
345
+ result = temporary_variable(variable.type, +variable.value)
346
+ when "-"
347
+ result = temporary_variable(variable.type, -variable.value)
348
+ when "~"
349
+ result = temporary_variable(variable.type, ~variable.value)
350
+ when "!"
351
+ result = temporary_variable(int_type, !variable.value)
352
+ else
353
+ # NOTREACHED
354
+ end
355
+
356
+ notify_unary_arithmetic_expr_evaled(node, variable, result)
357
+ return result
358
+ end
359
+ end
360
+
361
+ temporary_variable
362
+ end
363
+
364
+ def execute_cast_expression(node, object)
365
+ resolve_unresolved_type(node.type_name)
366
+
367
+ variable = object_to_variable(object)
368
+ converted =
369
+ do_conversion(variable, node.type_name.type) ||
370
+ temporary_variable(node.type_name.type)
371
+
372
+ notify_explicit_conv_performed(node, variable, converted)
373
+ converted
374
+ end
375
+
376
+ def execute_multiplicative_expression(node, lhs_object, rhs_object)
377
+ if lhs_object.function? || rhs_object.function?
378
+ return temporary_variable
379
+ end
380
+
381
+ lhs_variable = lhs_object
382
+ rhs_variable = rhs_object
383
+
384
+ unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
385
+ return temporary_variable
386
+ end
387
+
388
+ unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
389
+ return temporary_variable
390
+ end
391
+
392
+ lhs_converted, rhs_converted =
393
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
394
+
395
+ unless lhs_variable == lhs_converted
396
+ notify_implicit_conv_performed(node.lhs_operand,
397
+ lhs_variable, lhs_converted)
398
+ end
399
+
400
+ unless rhs_variable == rhs_converted
401
+ notify_implicit_conv_performed(node.rhs_operand,
402
+ rhs_variable, rhs_converted)
403
+ end
404
+
405
+ case node.operator.type
406
+ when "*"
407
+ # NOTE: Domain of the arithmetic result value will be restricted by
408
+ # min-max of the variable type.
409
+ result = temporary_variable(lhs_converted.type,
410
+ lhs_converted.value * rhs_converted.value)
411
+ when "/"
412
+ # NOTE: Domain of the arithmetic result value will be restricted by
413
+ # min-max of the variable type.
414
+ # NOTE: "Div by 0" semantics is implemented in value-value arithmetic.
415
+ result = temporary_variable(lhs_converted.type,
416
+ lhs_converted.value / rhs_converted.value)
417
+ when "%"
418
+ # NOTE: Domain of the arithmetic result value will be restricted by
419
+ # min-max of the variable type.
420
+ # NOTE: "Div by 0" semantics is implemented in value-value arithmetic.
421
+ result = temporary_variable(lhs_converted.type,
422
+ lhs_converted.value % rhs_converted.value)
423
+ else
424
+ # NOTREACHED
425
+ end
426
+
427
+ notify_multiplicative_expr_evaled(node,
428
+ lhs_variable, rhs_variable, result)
429
+ result
430
+ end
431
+
432
+ def execute_additive_expression(node, lhs_object, rhs_object)
433
+ if lhs_object.function? || rhs_object.function?
434
+ return temporary_variable
435
+ end
436
+
437
+ lhs_variable = lhs_object
438
+ rhs_variable = rhs_object
439
+
440
+ unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
441
+ return temporary_variable
442
+ end
443
+
444
+ unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
445
+ return temporary_variable
446
+ end
447
+
448
+ lhs_converted, rhs_converted =
449
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
450
+
451
+ unless lhs_variable == lhs_converted
452
+ notify_implicit_conv_performed(node.lhs_operand,
453
+ lhs_variable, lhs_converted)
454
+ end
455
+
456
+ unless rhs_variable == rhs_converted
457
+ notify_implicit_conv_performed(node.rhs_operand,
458
+ rhs_variable, rhs_converted)
459
+ end
460
+
461
+ case node.operator.type
462
+ when "+"
463
+ # NOTE: Domain of the arithmetic result value will be restricted by
464
+ # min-max of the variable type.
465
+ result = temporary_variable(lhs_converted.type,
466
+ lhs_converted.value + rhs_converted.value)
467
+ when "-"
468
+ # NOTE: Domain of the arithmetic result value will be restricted by
469
+ # min-max of the variable type.
470
+ result = temporary_variable(lhs_converted.type,
471
+ lhs_converted.value - rhs_converted.value)
472
+ else
473
+ # NOTREACHED
474
+ end
475
+
476
+ notify_additive_expr_evaled(node, lhs_variable, rhs_variable, result)
477
+ result
478
+ end
479
+
480
+ def execute_shift_expression(node, lhs_object, rhs_object)
481
+ if lhs_object.function? || rhs_object.function?
482
+ return temporary_variable
483
+ end
484
+
485
+ lhs_variable = lhs_object
486
+ rhs_variable = rhs_object
487
+
488
+ unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
489
+ return temporary_variable
490
+ end
491
+
492
+ unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
493
+ return temporary_variable
494
+ end
495
+
496
+ # NOTE: The ISO C99 standard saids;
497
+ #
498
+ # 6.5.7 Bitwise shift operators
499
+ #
500
+ # 3 The integer promotions are performed on each of the operands. The
501
+ # type of the result is that of the promoted left operand. If the
502
+ # value of the right operand is negative or is greater than or equal to
503
+ # the width of the promoted left operand, the behavior is undefined.
504
+
505
+ lhs_converted = do_integer_promotion(lhs_variable)
506
+ unless lhs_variable == lhs_converted
507
+ notify_implicit_conv_performed(node.lhs_operand,
508
+ lhs_variable, lhs_converted)
509
+ end
510
+
511
+ rhs_converted = do_integer_promotion(rhs_variable)
512
+ unless rhs_variable == rhs_converted
513
+ notify_implicit_conv_performed(node.rhs_operand,
514
+ rhs_variable, rhs_converted)
515
+ end
516
+
517
+ case node.operator.type
518
+ when "<<"
519
+ # NOTE: Domain of the arithmetic result value will be restricted by
520
+ # min-max of the variable type.
521
+ result = temporary_variable(lhs_converted.type,
522
+ lhs_converted.value << rhs_converted.value)
523
+ when ">>"
524
+ # NOTE: Domain of the arithmetic result value will be restricted by
525
+ # min-max of the variable type.
526
+ result = temporary_variable(lhs_converted.type,
527
+ lhs_converted.value >> rhs_converted.value)
528
+ else
529
+ # NOTREACHED
530
+ end
531
+
532
+ notify_shift_expr_evaled(node, lhs_variable, rhs_variable, result)
533
+ result
534
+ end
535
+
536
+ def execute_and_expression(node, lhs_object, rhs_object)
537
+ if lhs_object.function? || rhs_object.function?
538
+ return temporary_variable
539
+ end
540
+
541
+ lhs_variable = lhs_object
542
+ rhs_variable = rhs_object
543
+
544
+ unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
545
+ return temporary_variable
546
+ end
547
+
548
+ unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
549
+ return temporary_variable
550
+ end
551
+
552
+ lhs_converted, rhs_converted =
553
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
554
+
555
+ unless lhs_variable == lhs_converted
556
+ notify_implicit_conv_performed(node.lhs_operand,
557
+ lhs_variable, lhs_converted)
558
+ end
559
+
560
+ unless rhs_variable == rhs_converted
561
+ notify_implicit_conv_performed(node.rhs_operand,
562
+ rhs_variable, rhs_converted)
563
+ end
564
+
565
+ # NOTE: Domain of the arithmetic result value will be restricted by
566
+ # min-max of the variable type.
567
+ result = temporary_variable(lhs_converted.type,
568
+ lhs_converted.value & rhs_converted.value)
569
+
570
+ notify_and_expr_evaled(node, lhs_variable, rhs_variable, result)
571
+ result
572
+ end
573
+
574
+ def execute_exclusive_or_expression(node, lhs_object, rhs_object)
575
+ if lhs_object.function? || rhs_object.function?
576
+ return temporary_variable
577
+ end
578
+
579
+ lhs_variable = lhs_object
580
+ rhs_variable = rhs_object
581
+
582
+ unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
583
+ return temporary_variable
584
+ end
585
+
586
+ unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
587
+ return temporary_variable
588
+ end
589
+
590
+ lhs_converted, rhs_converted =
591
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
592
+
593
+ unless lhs_variable == lhs_converted
594
+ notify_implicit_conv_performed(node.lhs_operand,
595
+ lhs_variable, lhs_converted)
596
+ end
597
+
598
+ unless rhs_variable == rhs_converted
599
+ notify_implicit_conv_performed(node.rhs_operand,
600
+ rhs_variable, rhs_converted)
601
+ end
602
+
603
+ # NOTE: Domain of the arithmetic result value will be restricted by
604
+ # min-max of the variable type.
605
+ result = temporary_variable(lhs_converted.type,
606
+ lhs_converted.value ^ rhs_converted.value)
607
+
608
+ notify_exclusive_or_expr_evaled(node, lhs_variable, rhs_variable, result)
609
+ result
610
+ end
611
+
612
+ def execute_inclusive_or_expression(node, lhs_object, rhs_object)
613
+ if lhs_object.function? || rhs_object.function?
614
+ return temporary_variable
615
+ end
616
+
617
+ lhs_variable = lhs_object
618
+ rhs_variable = rhs_object
619
+
620
+ unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
621
+ return temporary_variable
622
+ end
623
+
624
+ unless lhs_variable.value.scalar? && rhs_variable.type.scalar?
625
+ return temporary_variable
626
+ end
627
+
628
+ lhs_converted, rhs_converted =
629
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
630
+
631
+ unless lhs_variable == lhs_converted
632
+ notify_implicit_conv_performed(node.lhs_operand,
633
+ lhs_variable, lhs_converted)
634
+ end
635
+
636
+ unless rhs_variable == rhs_converted
637
+ notify_implicit_conv_performed(node.rhs_operand,
638
+ rhs_variable, rhs_converted)
639
+ end
640
+
641
+ # NOTE: Domain of the arithmetic result value will be restricted by
642
+ # min-max of the variable type.
643
+ result = temporary_variable(lhs_converted.type,
644
+ lhs_converted.value | rhs_converted.value)
645
+
646
+ notify_inclusive_or_expr_evaled(node, lhs_variable, rhs_variable, result)
647
+ result
648
+ end
649
+
650
+ def execute_simple_assignment_expression(node, lhs_object, rhs_object)
651
+ if lhs_object.variable?
652
+ lhs_variable = lhs_object
653
+ else
654
+ return lhs_object
655
+ end
656
+
657
+ rhs_variable = object_to_variable(rhs_object)
658
+ unless rhs_variable == rhs_object
659
+ notify_implicit_conv_performed(node.rhs_operand,
660
+ rhs_object, rhs_variable)
661
+ end
662
+
663
+ if lhs_variable.type.same_as?(rhs_object.type)
664
+ rhs_converted = rhs_object
665
+ else
666
+ rhs_converted =
667
+ do_conversion(rhs_object, lhs_variable.type) ||
668
+ temporary_variable(lhs_variable.type)
669
+ notify_implicit_conv_performed(node.rhs_operand,
670
+ rhs_object, rhs_converted)
671
+ end
672
+
673
+ # NOTE: Domain of the arithmetic result value will be restricted by
674
+ # min-max of the variable type.
675
+ # NOTE: Even if rhs_object is a NamedVariable, new value will be
676
+ # instantiated in value-coercing.
677
+ # So, value-aliasing never occurs.
678
+ lhs_variable.assign!(rhs_converted.value.to_defined_value)
679
+ notify_assignment_expr_evaled(node, lhs_variable, rhs_converted)
680
+ notify_variable_value_updated(node, lhs_variable)
681
+
682
+ lhs_variable
683
+ end
684
+
685
+ def execute_compound_assignment_expression(node, lhs_object, rhs_object)
686
+ if lhs_object.variable?
687
+ lhs_variable = lhs_object
688
+ else
689
+ return lhs_object
690
+ end
691
+
692
+ rhs_variable = object_to_variable(rhs_object)
693
+ unless rhs_variable == rhs_object
694
+ notify_implicit_conv_performed(node.rhs_operand,
695
+ rhs_object, rhs_variable)
696
+ end
697
+
698
+ unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
699
+ return lhs_variable
700
+ end
701
+
702
+ case node.operator.type
703
+ when "*="
704
+ execute_mul_then_assign_expression(node, lhs_variable, rhs_variable)
705
+ when "/="
706
+ execute_div_then_assign_expression(node, lhs_variable, rhs_variable)
707
+ when "%="
708
+ execute_mod_then_assign_expression(node, lhs_variable, rhs_variable)
709
+ when "+="
710
+ execute_add_then_assign_expression(node, lhs_variable, rhs_variable)
711
+ when "-="
712
+ execute_sub_then_assign_expression(node, lhs_variable, rhs_variable)
713
+ when "<<="
714
+ execute_shl_then_assign_expression(node, lhs_variable, rhs_variable)
715
+ when ">>="
716
+ execute_shr_then_assign_expression(node, lhs_variable, rhs_variable)
717
+ when "&="
718
+ execute_and_then_assign_expression(node, lhs_variable, rhs_variable)
719
+ when "^="
720
+ execute_xor_then_assign_expression(node, lhs_variable, rhs_variable)
721
+ when "|="
722
+ execute_ior_then_assign_expression(node, lhs_variable, rhs_variable)
723
+ end
724
+
725
+ notify_variable_value_updated(node, lhs_variable)
726
+
727
+ lhs_variable
728
+ end
729
+
730
+ def execute_mul_then_assign_expression(node, lhs_variable, rhs_variable)
731
+ lhs_converted, rhs_converted =
732
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
733
+
734
+ unless lhs_variable == lhs_converted
735
+ notify_implicit_conv_performed(node.lhs_operand,
736
+ lhs_variable, lhs_converted)
737
+ end
738
+
739
+ unless rhs_variable == rhs_converted
740
+ notify_implicit_conv_performed(node.rhs_operand,
741
+ rhs_variable, rhs_converted)
742
+ end
743
+
744
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
745
+ result_value = lhs_converted.value * rhs_converted.value
746
+ else
747
+ result_value = lhs_converted.value
748
+ end
749
+
750
+ result_variable = temporary_variable(lhs_converted.type, result_value)
751
+
752
+ notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
753
+ result_variable)
754
+
755
+ if lhs_variable.type.same_as?(result_variable.type)
756
+ result_converted = result_variable
757
+ else
758
+ result_converted =
759
+ do_conversion(result_variable, lhs_variable.type) ||
760
+ temporary_variable(lhs_variable.type)
761
+ notify_implicit_conv_performed(node.lhs_operand,
762
+ result_variable, result_converted)
763
+ end
764
+
765
+ # NOTE: Domain of the arithmetic result value will be restricted by
766
+ # min-max of the variable type.
767
+ lhs_variable.assign!(result_converted.value)
768
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
769
+ end
770
+
771
+ def execute_div_then_assign_expression(node, lhs_variable, rhs_variable)
772
+ lhs_converted, rhs_converted =
773
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
774
+
775
+ unless lhs_variable == lhs_converted
776
+ notify_implicit_conv_performed(node.lhs_operand,
777
+ lhs_variable, lhs_converted)
778
+ end
779
+
780
+ unless rhs_variable == rhs_converted
781
+ notify_implicit_conv_performed(node.rhs_operand,
782
+ rhs_variable, rhs_converted)
783
+ end
784
+
785
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
786
+ # NOTE: "Div by 0" semantics is implemented in value-value arithmetic.
787
+ result_value = lhs_converted.value / rhs_converted.value
788
+ else
789
+ result_value = lhs_converted.value
790
+ end
791
+
792
+ result_variable = temporary_variable(lhs_converted.type, result_value)
793
+
794
+ notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
795
+ result_variable)
796
+
797
+ if lhs_variable.type.same_as?(result_variable.type)
798
+ result_converted = result_variable
799
+ else
800
+ result_converted =
801
+ do_conversion(result_variable, lhs_variable.type) ||
802
+ temporary_variable(lhs_variable.type)
803
+ notify_implicit_conv_performed(node.lhs_operand,
804
+ result_variable, result_converted)
805
+ end
806
+
807
+ # NOTE: Domain of the arithmetic result value will be restricted by
808
+ # min-max of the variable type.
809
+ lhs_variable.assign!(result_converted.value)
810
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
811
+ end
812
+
813
+ def execute_mod_then_assign_expression(node, lhs_variable, rhs_variable)
814
+ lhs_converted, rhs_converted =
815
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
816
+
817
+ unless lhs_variable == lhs_converted
818
+ notify_implicit_conv_performed(node.lhs_operand,
819
+ lhs_variable, lhs_converted)
820
+ end
821
+
822
+ unless rhs_variable == rhs_converted
823
+ notify_implicit_conv_performed(node.rhs_operand,
824
+ rhs_variable, rhs_converted)
825
+ end
826
+
827
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
828
+ # NOTE: "Div by 0" semantics is implemented in value-value arithmetic.
829
+ result_value = lhs_converted.value % rhs_converted.value
830
+ else
831
+ result_value = lhs_converted.value
832
+ end
833
+
834
+ result_variable = temporary_variable(lhs_converted.type, result_value)
835
+
836
+ notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
837
+ result_variable)
838
+
839
+ if lhs_variable.type.same_as?(result_variable.type)
840
+ result_converted = result_variable
841
+ else
842
+ result_converted =
843
+ do_conversion(result_variable, lhs_variable.type) ||
844
+ temporary_variable(lhs_variable.type)
845
+ notify_implicit_conv_performed(node.lhs_operand,
846
+ result_variable, result_converted)
847
+ end
848
+
849
+ # NOTE: Domain of the arithmetic result value will be restricted by
850
+ # min-max of the variable type.
851
+ lhs_variable.assign!(result_converted.value)
852
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
853
+ end
854
+
855
+ def execute_add_then_assign_expression(node, lhs_variable, rhs_variable)
856
+ lhs_converted, rhs_converted =
857
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
858
+
859
+ unless lhs_variable == lhs_converted
860
+ notify_implicit_conv_performed(node.lhs_operand,
861
+ lhs_variable, lhs_converted)
862
+ end
863
+
864
+ unless rhs_variable == rhs_converted
865
+ notify_implicit_conv_performed(node.rhs_operand,
866
+ rhs_variable, rhs_converted)
867
+ end
868
+
869
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
870
+ result_value = lhs_converted.value + rhs_converted.value
871
+ else
872
+ result_value = lhs_converted.value
873
+ end
874
+
875
+ result_variable = temporary_variable(lhs_converted.type, result_value)
876
+
877
+ notify_additive_expr_evaled(node, lhs_variable, rhs_variable,
878
+ result_variable)
879
+
880
+ if lhs_variable.type.same_as?(result_variable.type)
881
+ result_converted = result_variable
882
+ else
883
+ result_converted =
884
+ do_conversion(result_variable, lhs_variable.type) ||
885
+ temporary_variable(lhs_variable.type)
886
+ notify_implicit_conv_performed(node.lhs_operand,
887
+ result_variable, result_converted)
888
+ end
889
+
890
+ # NOTE: Domain of the arithmetic result value will be restricted by
891
+ # min-max of the variable type.
892
+ lhs_variable.assign!(result_converted.value)
893
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
894
+ end
895
+
896
+ def execute_sub_then_assign_expression(node, lhs_variable, rhs_variable)
897
+ lhs_converted, rhs_converted =
898
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
899
+
900
+ unless lhs_variable == lhs_converted
901
+ notify_implicit_conv_performed(node.lhs_operand,
902
+ lhs_variable, lhs_converted)
903
+ end
904
+
905
+ unless rhs_variable == rhs_converted
906
+ notify_implicit_conv_performed(node.rhs_operand,
907
+ rhs_variable, rhs_converted)
908
+ end
909
+
910
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
911
+ result_value = lhs_converted.value - rhs_converted.value
912
+ else
913
+ result_value = lhs_converted.value
914
+ end
915
+
916
+ result_variable = temporary_variable(lhs_converted.type, result_value)
917
+
918
+ notify_additive_expr_evaled(node, lhs_variable, rhs_variable,
919
+ result_variable)
920
+
921
+ if lhs_variable.type.same_as?(result_variable.type)
922
+ result_converted = result_variable
923
+ else
924
+ result_converted =
925
+ do_conversion(result_variable, lhs_variable.type) ||
926
+ temporary_variable(lhs_variable.type)
927
+ notify_implicit_conv_performed(node.lhs_operand,
928
+ result_variable, result_converted)
929
+ end
930
+
931
+ # NOTE: Domain of the arithmetic result value will be restricted by
932
+ # min-max of the variable type.
933
+ lhs_variable.assign!(result_converted.value)
934
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
935
+ end
936
+
937
+ def execute_shl_then_assign_expression(node, lhs_variable, rhs_variable)
938
+ # NOTE: The ISO C99 standard saids;
939
+ #
940
+ # 6.5.7 Bitwise shift operators
941
+ #
942
+ # 3 The integer promotions are performed on each of the operands. The
943
+ # type of the result is that of the promoted left operand. If the
944
+ # value of the right operand is negative or is greater than or equal to
945
+ # the width of the promoted left operand, the behavior is undefined.
946
+
947
+ lhs_converted = do_integer_promotion(lhs_variable)
948
+ unless lhs_variable == lhs_converted
949
+ notify_implicit_conv_performed(node.lhs_operand,
950
+ lhs_variable, lhs_converted)
951
+ end
952
+
953
+ rhs_converted = do_integer_promotion(rhs_variable)
954
+ unless rhs_variable == rhs_converted
955
+ notify_implicit_conv_performed(node.rhs_operand,
956
+ rhs_variable, rhs_converted)
957
+ end
958
+
959
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
960
+ result_value = lhs_converted.value << rhs_converted.value
961
+ else
962
+ result_value = lhs_converted.value
963
+ end
964
+
965
+ result_variable = temporary_variable(lhs_converted.type, result_value)
966
+
967
+ notify_shift_expr_evaled(node, lhs_converted, rhs_converted,
968
+ result_variable)
969
+
970
+ if lhs_variable.type.same_as?(result_variable.type)
971
+ result_converted = result_variable
972
+ else
973
+ result_converted =
974
+ do_conversion(result_variable, lhs_variable.type) ||
975
+ temporary_variable(lhs_variable.type)
976
+ notify_implicit_conv_performed(node.lhs_operand,
977
+ result_variable, result_converted)
978
+ end
979
+
980
+ # NOTE: Domain of the arithmetic result value will be restricted by
981
+ # min-max of the variable type.
982
+ lhs_variable.assign!(result_converted.value)
983
+ end
984
+
985
+ def execute_shr_then_assign_expression(node, lhs_variable, rhs_variable)
986
+ # NOTE: The ISO C99 standard saids;
987
+ #
988
+ # 6.5.7 Bitwise shift operators
989
+ #
990
+ # 3 The integer promotions are performed on each of the operands. The
991
+ # type of the result is that of the promoted left operand. If the
992
+ # value of the right operand is negative or is greater than or equal to
993
+ # the width of the promoted left operand, the behavior is undefined.
994
+
995
+ lhs_converted = do_integer_promotion(lhs_variable)
996
+ unless lhs_variable == lhs_converted
997
+ notify_implicit_conv_performed(node.lhs_operand,
998
+ lhs_variable, lhs_converted)
999
+ end
1000
+
1001
+ rhs_converted = do_integer_promotion(rhs_variable)
1002
+ unless rhs_variable == rhs_converted
1003
+ notify_implicit_conv_performed(node.rhs_operand,
1004
+ rhs_variable, rhs_converted)
1005
+ end
1006
+
1007
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
1008
+ result_value = lhs_converted.value >> rhs_converted.value
1009
+ else
1010
+ result_value = lhs_converted.value
1011
+ end
1012
+
1013
+ result_variable = temporary_variable(lhs_converted.type, result_value)
1014
+
1015
+ notify_shift_expr_evaled(node, lhs_converted, rhs_converted,
1016
+ result_variable)
1017
+
1018
+ if lhs_variable.type.same_as?(result_variable.type)
1019
+ result_converted = result_variable
1020
+ else
1021
+ result_converted =
1022
+ do_conversion(result_variable, lhs_variable.type) ||
1023
+ temporary_variable(lhs_variable.type)
1024
+ notify_implicit_conv_performed(node.lhs_operand,
1025
+ result_variable, result_converted)
1026
+ end
1027
+
1028
+ # NOTE: Domain of the arithmetic result value will be restricted by
1029
+ # min-max of the variable type.
1030
+ lhs_variable.assign!(result_converted.value)
1031
+ end
1032
+
1033
+ def execute_and_then_assign_expression(node, lhs_variable, rhs_variable)
1034
+ lhs_converted, rhs_converted =
1035
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
1036
+
1037
+ unless lhs_variable == lhs_converted
1038
+ notify_implicit_conv_performed(node.lhs_operand,
1039
+ lhs_variable, lhs_converted)
1040
+ end
1041
+
1042
+ unless rhs_variable == rhs_converted
1043
+ notify_implicit_conv_performed(node.rhs_operand,
1044
+ rhs_variable, rhs_converted)
1045
+ end
1046
+
1047
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
1048
+ result_value = lhs_converted.value & rhs_converted.value
1049
+ else
1050
+ result_value = lhs_converted.value
1051
+ end
1052
+
1053
+ result_variable = temporary_variable(lhs_converted.type, result_value)
1054
+
1055
+ notify_and_expr_evaled(node, lhs_variable, rhs_variable, result_variable)
1056
+
1057
+ if lhs_variable.type.same_as?(result_variable.type)
1058
+ result_converted = result_variable
1059
+ else
1060
+ result_converted =
1061
+ do_conversion(result_variable, lhs_variable.type) ||
1062
+ temporary_variable(lhs_variable.type)
1063
+ notify_implicit_conv_performed(node.lhs_operand,
1064
+ result_variable, result_converted)
1065
+ end
1066
+
1067
+ # NOTE: Domain of the arithmetic result value will be restricted by
1068
+ # min-max of the variable type.
1069
+ lhs_variable.assign!(result_converted.value)
1070
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
1071
+ end
1072
+
1073
+ def execute_xor_then_assign_expression(node, lhs_variable, rhs_variable)
1074
+ lhs_converted, rhs_converted =
1075
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
1076
+
1077
+ unless lhs_variable == lhs_converted
1078
+ notify_implicit_conv_performed(node.lhs_operand,
1079
+ lhs_variable, lhs_converted)
1080
+ end
1081
+
1082
+ unless rhs_variable == rhs_converted
1083
+ notify_implicit_conv_performed(node.rhs_operand,
1084
+ rhs_variable, rhs_converted)
1085
+ end
1086
+
1087
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
1088
+ result_value = lhs_converted.value ^ rhs_converted.value
1089
+ else
1090
+ result_value = lhs_converted.value
1091
+ end
1092
+
1093
+ result_variable = temporary_variable(lhs_converted.type, result_value)
1094
+
1095
+ notify_exclusive_or_expr_evaled(node, lhs_variable, rhs_variable,
1096
+ result_variable)
1097
+
1098
+ if lhs_variable.type.same_as?(result_variable.type)
1099
+ result_converted = result_variable
1100
+ else
1101
+ result_converted =
1102
+ do_conversion(result_variable, lhs_variable.type) ||
1103
+ temporary_variable(lhs_variable.type)
1104
+ notify_implicit_conv_performed(node.lhs_operand,
1105
+ result_variable, result_converted)
1106
+ end
1107
+
1108
+ # NOTE: Domain of the arithmetic result value will be restricted by
1109
+ # min-max of the variable type.
1110
+ lhs_variable.assign!(result_converted.value)
1111
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
1112
+ end
1113
+
1114
+ def execute_ior_then_assign_expression(node, lhs_variable, rhs_variable)
1115
+ lhs_converted, rhs_converted =
1116
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
1117
+
1118
+ unless lhs_variable == lhs_converted
1119
+ notify_implicit_conv_performed(node.lhs_operand,
1120
+ lhs_variable, lhs_converted)
1121
+ end
1122
+
1123
+ unless rhs_variable == rhs_converted
1124
+ notify_implicit_conv_performed(node.rhs_operand,
1125
+ rhs_variable, rhs_converted)
1126
+ end
1127
+
1128
+ if lhs_converted.value.scalar? && rhs_converted.value.scalar?
1129
+ result_value = lhs_converted.value | rhs_converted.value
1130
+ else
1131
+ result_value = lhs_converted.value
1132
+ end
1133
+
1134
+ result_variable = temporary_variable(lhs_converted.type, result_value)
1135
+
1136
+ notify_inclusive_or_expr_evaled(node, lhs_variable, rhs_variable,
1137
+ result_variable)
1138
+
1139
+ if lhs_variable.type.same_as?(result_variable.type)
1140
+ result_converted = result_variable
1141
+ else
1142
+ result_converted =
1143
+ do_conversion(result_variable, lhs_variable.type) ||
1144
+ temporary_variable(lhs_variable.type)
1145
+ notify_implicit_conv_performed(node.lhs_operand,
1146
+ result_variable, result_converted)
1147
+ end
1148
+
1149
+ # NOTE: Domain of the arithmetic result value will be restricted by
1150
+ # min-max of the variable type.
1151
+ lhs_variable.assign!(result_converted.value)
1152
+ notify_assignment_expr_evaled(node, lhs_variable, result_converted)
1153
+ end
1154
+
1155
+ def variable_reassigning_context(&block)
1156
+ expr_context_stack.push(:variable_reassigning)
1157
+ yield
1158
+ ensure
1159
+ expr_context_stack.pop
1160
+ end
1161
+
1162
+ def variable_reassigning?
1163
+ expr_context_stack.last == :variable_reassigning
1164
+ end
1165
+
1166
+ def function_calling_context(&block)
1167
+ expr_context_stack.push(:function_calling)
1168
+ yield
1169
+ ensure
1170
+ expr_context_stack.pop
1171
+ end
1172
+
1173
+ def function_calling?
1174
+ expr_context_stack.last == :function_calling
1175
+ end
1176
+
1177
+ def expr_context_stack
1178
+ @expr_context_stack ||= []
1179
+ end
1180
+
1181
+ def char_array_value(string_literal)
1182
+ chars = string_literal.chars.map { |ch| ScalarValue.of(ch.ord) }
1183
+ ArrayValue.new(chars + [ScalarValue.of("\0".ord)])
1184
+ end
1185
+
1186
+ def wchar_array_value(string_literal)
1187
+ chars = string_literal.chars.map { |ch| ScalarValue.of(ch.ord) }
1188
+ ArrayValue.new(chars + [ScalarValue.of("\0".ord)])
1189
+ end
1190
+ end
1191
+
1192
+ module ExpressionEvaluator
1193
+ # NOTE: Host class of this module must include InterpreterMediator and
1194
+ # MonitorUtil.
1195
+
1196
+ include NotifierMediator
1197
+ include ConstantEvaluator
1198
+ include Conversion
1199
+ include ExpressionUtil
1200
+
1201
+ def visit_error_expression(node)
1202
+ checkpoint(node.location)
1203
+
1204
+ temporary_variable
1205
+ end
1206
+
1207
+ def visit_object_specifier(node)
1208
+ checkpoint(node.location)
1209
+
1210
+ if variable = variable_named(node.identifier.value)
1211
+ notify_variable_referred(node, variable)
1212
+ unless variable_reassigning?
1213
+ notify_variable_value_referred(node, variable)
1214
+ end
1215
+ variable.declarations_and_definitions.each do |decl_or_def|
1216
+ decl_or_def.mark_as_referred_by(node.identifier)
1217
+ end
1218
+ if variable.type.array?
1219
+ variable = temporary_variable(pointer_type(variable.type.base_type),
1220
+ pointer_value_of(variable))
1221
+ end
1222
+ return variable
1223
+ end
1224
+
1225
+ if function = function_named(node.identifier.value)
1226
+ unless function_calling?
1227
+ notify_function_referred(node, function)
1228
+ end
1229
+ function.declarations_and_definitions.each do |decl_or_def|
1230
+ decl_or_def.mark_as_referred_by(node.identifier)
1231
+ end
1232
+ return function
1233
+ end
1234
+
1235
+ if enumerator = enumerator_named(node.identifier.value)
1236
+ enumerator.mark_as_referred_by(node.identifier)
1237
+ return temporary_variable(int_type, ScalarValue.of(enumerator.value))
1238
+ end
1239
+
1240
+ define_implicit_function(node.identifier.value)
1241
+ end
1242
+
1243
+ def visit_constant_specifier(node)
1244
+ checkpoint(node.location)
1245
+
1246
+ if variable = eval_constant(node)
1247
+ notify_constant_referred(node, variable)
1248
+ variable
1249
+ else
1250
+ temporary_variable
1251
+ end
1252
+ end
1253
+
1254
+ def visit_string_literal_specifier(node)
1255
+ checkpoint(node.location)
1256
+
1257
+ case node.literal.value
1258
+ when /\A"(.*)"\z/
1259
+ array = temporary_variable(array_type(char_type, $1.length + 1),
1260
+ char_array_value($1))
1261
+ when /\AL"(.*)"\z/i
1262
+ array = temporary_variable(array_type(wchar_type, $1.length + 1),
1263
+ wchar_array_value($1))
1264
+ else
1265
+ return temporary_variable(pointer_type(char_type))
1266
+ end
1267
+
1268
+ temporary_variable(pointer_type(array.type.base_type),
1269
+ pointer_value_of(array))
1270
+ end
1271
+
1272
+ def visit_null_constant_specifier(node)
1273
+ checkpoint(node.location)
1274
+
1275
+ # TODO: NULL may not be 0 on some environments.
1276
+ # Representation of NULL should be configurable?
1277
+ temporary_variable(pointer_type(void_type), ScalarValue.of(0))
1278
+ end
1279
+
1280
+ def visit_grouped_expression(node)
1281
+ checkpoint(node.location)
1282
+
1283
+ node.expression.accept(self)
1284
+ end
1285
+
1286
+ def visit_array_subscript_expression(node)
1287
+ checkpoint(node.location)
1288
+
1289
+ execute_array_subscript_expression(
1290
+ node, node.expression.accept(self), node.array_subscript.accept(self))
1291
+ end
1292
+
1293
+ def visit_function_call_expression(node)
1294
+ checkpoint(node.location)
1295
+
1296
+ object = function_calling_context { node.expression.accept(self) }
1297
+ args = node.argument_expressions.map { |expr| [expr.accept(self), expr] }
1298
+
1299
+ execute_function_call_expression(node, object, args)
1300
+ end
1301
+
1302
+ def visit_member_access_by_value_expression(node)
1303
+ checkpoint(node.location)
1304
+
1305
+ object = node.expression.accept(self)
1306
+
1307
+ execute_member_access_by_value_expression(node, object)
1308
+ end
1309
+
1310
+ def visit_member_access_by_pointer_expression(node)
1311
+ checkpoint(node.location)
1312
+
1313
+ object = node.expression.accept(self)
1314
+
1315
+ execute_member_access_by_pointer_expression(node, object)
1316
+ end
1317
+
1318
+ def visit_bit_access_by_value_expression(node)
1319
+ checkpoint(node.location)
1320
+
1321
+ # TODO: Should support the GCC extension.
1322
+ temporary_variable
1323
+ end
1324
+
1325
+ def visit_bit_access_by_pointer_expression(node)
1326
+ checkpoint(node.location)
1327
+
1328
+ # TODO: Should support the GCC extension.
1329
+ temporary_variable
1330
+ end
1331
+
1332
+ def visit_postfix_increment_expression(node)
1333
+ checkpoint(node.location)
1334
+
1335
+ object = variable_reassigning_context { node.operand.accept(self) }
1336
+
1337
+ execute_postfix_increment_expression(node, object)
1338
+ end
1339
+
1340
+ def visit_postfix_decrement_expression(node)
1341
+ checkpoint(node.location)
1342
+
1343
+ object = variable_reassigning_context { node.operand.accept(self) }
1344
+
1345
+ execute_postfix_decrement_expression(node, object)
1346
+ end
1347
+
1348
+ def visit_compound_literal_expression(node)
1349
+ checkpoint(node.location)
1350
+
1351
+ # TODO: Should support C99 features.
1352
+ temporary_variable(node.type_name.type)
1353
+ end
1354
+
1355
+ def visit_prefix_increment_expression(node)
1356
+ checkpoint(node.location)
1357
+
1358
+ object = variable_reassigning_context { node.operand.accept(self) }
1359
+
1360
+ execute_prefix_increment_expression(node, object)
1361
+ end
1362
+
1363
+ def visit_prefix_decrement_expression(node)
1364
+ checkpoint(node.location)
1365
+
1366
+ object = variable_reassigning_context { node.operand.accept(self) }
1367
+
1368
+ execute_prefix_decrement_expression(node, object)
1369
+ end
1370
+
1371
+ def visit_address_expression(node)
1372
+ checkpoint(node.location)
1373
+
1374
+ object = node.operand.accept(self)
1375
+ temporary_variable(pointer_type(object.type), pointer_value_of(object))
1376
+ end
1377
+
1378
+ def visit_indirection_expression(node)
1379
+ checkpoint(node.location)
1380
+
1381
+ object = node.operand.accept(self)
1382
+
1383
+ execute_indirection_expression(node, object)
1384
+ end
1385
+
1386
+ def visit_unary_arithmetic_expression(node)
1387
+ checkpoint(node.location)
1388
+
1389
+ object = node.operand.accept(self)
1390
+
1391
+ execute_unary_arithmetic_expression(node, object)
1392
+ end
1393
+
1394
+ def visit_sizeof_expression(node)
1395
+ checkpoint(node.location)
1396
+
1397
+ object = node.operand.accept(self)
1398
+ if object.variable?
1399
+ variable = object
1400
+ result = temporary_variable(
1401
+ int_type, ScalarValue.of(variable.type.aligned_byte_size))
1402
+ notify_sizeof_expr_evaled(node, variable, result)
1403
+ else
1404
+ result = temporary_variable(int_type)
1405
+ end
1406
+
1407
+ result
1408
+ end
1409
+
1410
+ def visit_sizeof_type_expression(node)
1411
+ checkpoint(node.location)
1412
+
1413
+ resolve_unresolved_type(node.operand)
1414
+
1415
+ result = temporary_variable(
1416
+ int_type, ScalarValue.of(node.operand.type.aligned_byte_size))
1417
+ notify_sizeof_type_expr_evaled(node, node.operand.type, result)
1418
+
1419
+ result
1420
+ end
1421
+
1422
+ def visit_alignof_expression(node)
1423
+ checkpoint(node.location)
1424
+
1425
+ object = node.operand.accept(self)
1426
+ if object.variable?
1427
+ variable = object
1428
+ temporary_variable(int_type,
1429
+ ScalarValue.of(variable.type.byte_alignment))
1430
+ else
1431
+ temporary_variable(int_type)
1432
+ end
1433
+ end
1434
+
1435
+ def visit_alignof_type_expression(node)
1436
+ checkpoint(node.location)
1437
+
1438
+ resolve_unresolved_type(node.operand)
1439
+
1440
+ temporary_variable(int_type,
1441
+ ScalarValue.of(node.operand.type.aligned_byte_size))
1442
+ end
1443
+
1444
+ def visit_cast_expression(node)
1445
+ checkpoint(node.location)
1446
+
1447
+ object = node.operand.accept(self)
1448
+
1449
+ execute_cast_expression(node, object)
1450
+ end
1451
+
1452
+ def visit_multiplicative_expression(node)
1453
+ checkpoint(node.location)
1454
+
1455
+ lhs_object = node.lhs_operand.accept(self)
1456
+ rhs_object = node.rhs_operand.accept(self)
1457
+
1458
+ execute_multiplicative_expression(node, lhs_object, rhs_object)
1459
+ end
1460
+
1461
+ def visit_additive_expression(node)
1462
+ checkpoint(node.location)
1463
+
1464
+ lhs_object = node.lhs_operand.accept(self)
1465
+ rhs_object = node.rhs_operand.accept(self)
1466
+
1467
+ execute_additive_expression(node, lhs_object, rhs_object)
1468
+ end
1469
+
1470
+ def visit_shift_expression(node)
1471
+ checkpoint(node.location)
1472
+
1473
+ lhs_object = node.lhs_operand.accept(self)
1474
+ rhs_object = node.rhs_operand.accept(self)
1475
+
1476
+ execute_shift_expression(node, lhs_object, rhs_object)
1477
+ end
1478
+
1479
+ def visit_relational_expression(node)
1480
+ checkpoint(node.location)
1481
+
1482
+ lhs_object = node.lhs_operand.accept(self)
1483
+ rhs_object = node.rhs_operand.accept(self)
1484
+
1485
+ if lhs_object.function? || rhs_object.function?
1486
+ return temporary_variable(int_type)
1487
+ end
1488
+
1489
+ lhs_variable = lhs_object
1490
+ rhs_variable = rhs_object
1491
+
1492
+ unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
1493
+ return temporary_variable(int_type)
1494
+ end
1495
+
1496
+ unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
1497
+ return temporary_variable(int_type)
1498
+ end
1499
+
1500
+ lhs_converted, rhs_converted =
1501
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
1502
+
1503
+ unless lhs_variable == lhs_converted
1504
+ notify_implicit_conv_performed(node.lhs_operand,
1505
+ lhs_variable, lhs_converted)
1506
+ end
1507
+
1508
+ unless rhs_variable == rhs_converted
1509
+ notify_implicit_conv_performed(node.rhs_operand,
1510
+ rhs_variable, rhs_converted)
1511
+ end
1512
+
1513
+ case node.operator.type
1514
+ when "<"
1515
+ result = temporary_variable(int_type,
1516
+ lhs_converted.value < rhs_converted.value)
1517
+ when ">"
1518
+ result = temporary_variable(int_type,
1519
+ lhs_converted.value > rhs_converted.value)
1520
+ when "<="
1521
+ result = temporary_variable(int_type,
1522
+ lhs_converted.value <= rhs_converted.value)
1523
+ when ">="
1524
+ result = temporary_variable(int_type,
1525
+ lhs_converted.value >= rhs_converted.value)
1526
+ else
1527
+ # NOTREACHED
1528
+ end
1529
+
1530
+ notify_relational_expr_evaled(node, lhs_converted, rhs_converted, result)
1531
+ result
1532
+ end
1533
+
1534
+ def visit_equality_expression(node)
1535
+ checkpoint(node.location)
1536
+
1537
+ lhs_object = node.lhs_operand.accept(self)
1538
+ rhs_object = node.rhs_operand.accept(self)
1539
+
1540
+ if lhs_object.function? || rhs_object.function?
1541
+ return temporary_variable(int_type)
1542
+ end
1543
+
1544
+ lhs_variable = lhs_object
1545
+ rhs_variable = rhs_object
1546
+
1547
+ unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
1548
+ return temporary_variable(int_type)
1549
+ end
1550
+
1551
+ unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
1552
+ return temporary_variable(int_type)
1553
+ end
1554
+
1555
+ lhs_converted, rhs_converted =
1556
+ do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
1557
+
1558
+ unless lhs_variable == lhs_converted
1559
+ notify_implicit_conv_performed(node.lhs_operand,
1560
+ lhs_variable, lhs_converted)
1561
+ end
1562
+
1563
+ unless rhs_variable == rhs_converted
1564
+ notify_implicit_conv_performed(node.rhs_operand,
1565
+ rhs_variable, rhs_converted)
1566
+ end
1567
+
1568
+ case node.operator.type
1569
+ when "=="
1570
+ result = temporary_variable(int_type,
1571
+ lhs_converted.value == rhs_converted.value)
1572
+ when "!="
1573
+ result = temporary_variable(int_type,
1574
+ lhs_converted.value != rhs_converted.value)
1575
+ else
1576
+ # NOTREACHED
1577
+ end
1578
+
1579
+ notify_equality_expr_evaled(node, lhs_converted, rhs_converted, result)
1580
+ result
1581
+ end
1582
+
1583
+ def visit_and_expression(node)
1584
+ checkpoint(node.location)
1585
+
1586
+ lhs_object = node.lhs_operand.accept(self)
1587
+ rhs_object = node.rhs_operand.accept(self)
1588
+
1589
+ execute_and_expression(node, lhs_object, rhs_object)
1590
+ end
1591
+
1592
+ def visit_exclusive_or_expression(node)
1593
+ checkpoint(node.location)
1594
+
1595
+ lhs_object = node.lhs_operand.accept(self)
1596
+ rhs_object = node.rhs_operand.accept(self)
1597
+
1598
+ execute_exclusive_or_expression(node, lhs_object, rhs_object)
1599
+ end
1600
+
1601
+ def visit_inclusive_or_expression(node)
1602
+ checkpoint(node.location)
1603
+
1604
+ lhs_object = node.lhs_operand.accept(self)
1605
+ rhs_object = node.rhs_operand.accept(self)
1606
+
1607
+ execute_inclusive_or_expression(node, lhs_object, rhs_object)
1608
+ end
1609
+
1610
+ def visit_logical_and_expression(node)
1611
+ checkpoint(node.location)
1612
+
1613
+ lhs_object = node.lhs_operand.accept(self)
1614
+ return temporary_variable(int_type) unless lhs_object.variable?
1615
+
1616
+ lhs_variable = lhs_object
1617
+ if lhs_variable.value.scalar? && lhs_variable.value.must_be_false?
1618
+ # NOTE: Doing the short-circuit evaluation.
1619
+ return temporary_variable(int_type, ScalarValue.of_false)
1620
+ end
1621
+
1622
+ rhs_object = node.rhs_operand.accept(self)
1623
+ return temporary_variable(int_type) unless rhs_object.variable?
1624
+
1625
+ rhs_variable = rhs_object
1626
+
1627
+ if lhs_variable.value.scalar? && rhs_variable.value.scalar?
1628
+ # NOTE: No usual-arithmetic-conversion.
1629
+ result = temporary_variable(
1630
+ int_type, lhs_variable.value.logical_and(rhs_variable.value))
1631
+ else
1632
+ result = temporary_variable(int_type)
1633
+ end
1634
+
1635
+ notify_logical_and_expr_evaled(node, lhs_variable, rhs_variable, result)
1636
+ result
1637
+ end
1638
+
1639
+ def visit_logical_or_expression(node)
1640
+ checkpoint(node.location)
1641
+
1642
+ lhs_object = node.lhs_operand.accept(self)
1643
+ return temporary_variable(int_type) unless lhs_object.variable?
1644
+
1645
+ lhs_variable = lhs_object
1646
+ if lhs_variable.value.scalar? && lhs_variable.value.must_be_true?
1647
+ # NOTE: Doing the short-circuit evaluation.
1648
+ return temporary_variable(int_type, ScalarValue.of_true)
1649
+ end
1650
+
1651
+ rhs_object = node.rhs_operand.accept(self)
1652
+ return temporary_variable(int_type) unless rhs_object.variable?
1653
+
1654
+ rhs_variable = rhs_object
1655
+
1656
+ if lhs_variable.value.scalar? && rhs_variable.value.scalar?
1657
+ # NOTE: No usual-arithmetic-conversion.
1658
+ result = temporary_variable(
1659
+ int_type, lhs_variable.value.logical_or(rhs_variable.value))
1660
+ else
1661
+ result = temporary_variable(int_type)
1662
+ end
1663
+
1664
+ notify_logical_or_expr_evaled(node, lhs_variable, rhs_variable, result)
1665
+ result
1666
+ end
1667
+
1668
+ def visit_conditional_expression(node)
1669
+ checkpoint(node.location)
1670
+
1671
+ condition_object = node.condition.accept(self)
1672
+
1673
+ if condition_object.variable?
1674
+ case
1675
+ when condition_object.value.must_be_true?
1676
+ result_object = node.then_expression.accept(self)
1677
+ when condition_object.value.must_be_false?
1678
+ result_object = node.else_expression.accept(self)
1679
+ else
1680
+ then_object = node.then_expression.accept(self)
1681
+ else_object = node.else_expression.accept(self)
1682
+ if then_object.variable? && else_object.variable?
1683
+ result_value =
1684
+ then_object.value.single_value_unified_with(else_object.value)
1685
+ result_object = temporary_variable(then_object.type, result_value)
1686
+ end
1687
+ end
1688
+ end
1689
+
1690
+ result = result_object ? result_object : temporary_variable
1691
+ notify_conditional_expr_evaled(node, condition_object, result)
1692
+ result
1693
+ end
1694
+
1695
+ def visit_simple_assignment_expression(node)
1696
+ checkpoint(node.location)
1697
+
1698
+ lhs_object = variable_reassigning_context {
1699
+ node.lhs_operand.accept(self)
1700
+ }
1701
+ rhs_object = node.rhs_operand.accept(self)
1702
+
1703
+ execute_simple_assignment_expression(node, lhs_object, rhs_object)
1704
+ end
1705
+
1706
+ def visit_compound_assignment_expression(node)
1707
+ checkpoint(node.location)
1708
+
1709
+ lhs_object = variable_reassigning_context {
1710
+ node.lhs_operand.accept(self)
1711
+ }
1712
+ rhs_object = node.rhs_operand.accept(self)
1713
+
1714
+ execute_compound_assignment_expression(node, lhs_object, rhs_object)
1715
+ end
1716
+
1717
+ def visit_comma_separated_expression(node)
1718
+ checkpoint(node.location)
1719
+
1720
+ node.expressions.map { |expression| expression.accept(self) }.last
1721
+ end
1722
+ end
1723
+
1724
+ end
1725
+ end