objc-torture.exp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. # Copyright (C) 1992-2015 Free Software Foundation, Inc.
  2. # This program is free software; you can redistribute it and/or modify
  3. # it under the terms of the GNU General Public License as published by
  4. # the Free Software Foundation; either version 3 of the License, or
  5. # (at your option) any later version.
  6. #
  7. # This program is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. # GNU General Public License for more details.
  11. #
  12. # You should have received a copy of the GNU General Public License
  13. # along with GCC; see the file COPYING3. If not see
  14. # <http://www.gnu.org/licenses/>.
  15. # This file was written by Rob Savoye. (rob@cygnus.com)
  16. load_lib file-format.exp
  17. load_lib target-supports.exp
  18. # Make sure that the runtime list is re-evaluated for each multilib.
  19. proc objc-set-runtime-options { dowhat args } {
  20. global OBJC_RUNTIME_OPTIONS
  21. set rtlist [list "-fgnu-runtime" ]
  22. # At present (4.6), the only NeXT runtime target is Darwin.
  23. # The previously used approach of testing trivial compiles is not reliable
  24. # for determining the absence of the NeXT runtime, since a non-Darwin
  25. # installation can have the objc headers present in the same locations
  26. # that Darwin uses. If NeXT is ported to another target, then it should
  27. # be listed here.
  28. if [istarget *-*-darwin*] {
  29. lappend rtlist "-fnext-runtime"
  30. }
  31. if [info exists OBJC_RUNTIME_OPTIONS] {
  32. foreach other $OBJC_RUNTIME_OPTIONS {
  33. # Don't do tests twice...
  34. if { ( $other == "-fnext-runtime" || $other == "-fgnu-runtime" ) } {
  35. continue
  36. }
  37. lappend rtlist $other
  38. }
  39. }
  40. set OBJC_RUNTIME_OPTIONS ""
  41. foreach type $rtlist {
  42. global srcdir subdir target_triplet tmpdir
  43. set options "additional_flags=$type"
  44. if [info exists args] {
  45. lappend options $args
  46. }
  47. verbose "options $options"
  48. if [info exists dowhat] {
  49. switch $dowhat {
  50. "compile" {
  51. # We should check that the generated asm is sensible, so do
  52. # the equivalent of -c.
  53. set compile_type "object"
  54. set output_file "trivial.o"
  55. set comp_output [objc_target_compile \
  56. "$srcdir/$subdir/trivial.m" "$output_file" "$compile_type" $options]
  57. remote_file build delete $output_file
  58. # If we get any error, then we failed.
  59. if ![string match "" $comp_output] then {
  60. continue;
  61. }
  62. }
  63. "execute" {
  64. set test_obj "trivial.exe"
  65. set comp_output [objc_target_compile \
  66. "$srcdir/$subdir/trivial.m" $test_obj "executable" $options]
  67. # If we get any error, then we failed.
  68. if ![string match "" $comp_output] then {
  69. remote_file build delete $test_obj
  70. continue;
  71. }
  72. set result [objc_load "$tmpdir/$test_obj" "" ""]
  73. set status [lindex $result 0]
  74. set output [lindex $result 1]
  75. remote_file build delete $test_obj
  76. if { $status != "pass" } {
  77. verbose -log "trivial execute failed with $status $output"
  78. continue;
  79. }
  80. }
  81. default {
  82. perror "$dowhat: not a valid objc-torture action"
  83. return ""
  84. }
  85. }
  86. } else {
  87. set test_obj "trivial.exe"
  88. set comp_output [objc_target_compile \
  89. "$srcdir/$subdir/trivial.m" $test_obj executable $options]
  90. # If we get any error, then we failed.
  91. remote_file build delete $test_obj
  92. if ![string match "" $comp_output] then {
  93. continue;
  94. }
  95. }
  96. lappend OBJC_RUNTIME_OPTIONS $type
  97. }
  98. verbose -log "Using the following runtimes: $OBJC_RUNTIME_OPTIONS"
  99. }
  100. # The default option list can be overridden by
  101. # TORTURE_OPTIONS="{ { list1 } ... { listN } }"
  102. if [info exists TORTURE_OPTIONS] {
  103. set OBJC_TORTURE_OPTIONS $TORTURE_OPTIONS
  104. } else {
  105. # It is theoretically beneficial to group all of the O2/O3 options together,
  106. # as in many cases the compiler will generate identical executables for
  107. # all of them--and the objc-torture testsuite will skip testing identical
  108. # executables multiple times.
  109. # Also note that -finline-functions is explicitly included in one of the
  110. # items below, even though -O3 is also specified, because some ports may
  111. # choose to disable inlining functions by default, even when optimizing.
  112. set OBJC_TORTURE_OPTIONS [list \
  113. " -O0 " \
  114. " -O1 " \
  115. " -O2 " \
  116. " -O3 -fomit-frame-pointer " \
  117. " -O3 -fomit-frame-pointer -funroll-loops " \
  118. " -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions " \
  119. " -O3 -g " \
  120. " -Os " ]
  121. }
  122. if [info exists ADDITIONAL_TORTURE_OPTIONS] {
  123. set OBJC_TORTURE_OPTIONS \
  124. [concat $OBJC_TORTURE_OPTIONS $ADDITIONAL_TORTURE_OPTIONS]
  125. }
  126. #
  127. # objc-torture-compile -- runs the Tege OBJC-torture test
  128. #
  129. # SRC is the full pathname of the testcase.
  130. # OPTION is the specific compiler flag we're testing (eg: -O2).
  131. #
  132. proc objc-torture-compile { src option } {
  133. global output
  134. global srcdir tmpdir
  135. global host_triplet
  136. set output "$tmpdir/[file tail [file rootname $src]].o"
  137. regsub "(?q)$srcdir/" $src "" testcase
  138. # If we couldn't rip $srcdir out of `src' then just do the best we can.
  139. # The point is to reduce the unnecessary noise in the logs. Don't strip
  140. # out too much because different testcases with the same name can confuse
  141. # `test-tool'.
  142. if [string match "/*" $testcase] {
  143. set testcase "[file tail [file dirname $src]]/[file tail $src]"
  144. }
  145. verbose "Testing $testcase, $option" 1
  146. # Run the compiler and analyze the results.
  147. set options ""
  148. lappend options "additional_flags=-w $option"
  149. set comp_output [objc_target_compile "$src" "$output" object $options]
  150. objc_check_compile $testcase $option $output $comp_output
  151. remote_file build delete $output
  152. }
  153. #
  154. # objc-torture-execute -- utility to compile and execute a testcase
  155. #
  156. # SRC is the full pathname of the testcase.
  157. #
  158. # If the testcase has an associated .x file, we source that to run the
  159. # test instead. We use .x so that we don't lengthen the existing filename
  160. # to more than 14 chars.
  161. #
  162. proc objc-torture-execute { src args } {
  163. global tmpdir tool srcdir output compiler_conditional_xfail_data
  164. if { [llength $args] > 0 } {
  165. set additional_flags [lindex $args 0]
  166. } else {
  167. set additional_flags ""
  168. }
  169. # Check for alternate driver.
  170. if [file exists [file rootname $src].x] {
  171. verbose "Using alternate driver [file rootname [file tail $src]].x" 2
  172. set done_p 0
  173. catch "set done_p \[source [file rootname $src].x\]"
  174. if { $done_p } {
  175. return
  176. }
  177. }
  178. # Look for a loop within the source code - if we don't find one,
  179. # don't pass -funroll[-all]-loops.
  180. global torture_with_loops torture_without_loops
  181. if [expr [search_for $src "for*("]+[search_for $src "while*("]] then {
  182. set option_list $torture_with_loops
  183. } else {
  184. set option_list $torture_without_loops
  185. }
  186. set executable $tmpdir/[file tail [file rootname $src].x]
  187. regsub "(?q)$srcdir/" $src "" testcase
  188. # If we couldn't rip $srcdir out of `src' then just do the best we can.
  189. # The point is to reduce the unnecessary noise in the logs. Don't strip
  190. # out too much because different testcases with the same name can confuse
  191. # `test-tool'.
  192. if [string match "/*" $testcase] {
  193. set testcase "[file tail [file dirname $src]]/[file tail $src]"
  194. }
  195. set count 0
  196. set oldstatus "foo"
  197. foreach option $option_list {
  198. if { $count > 0 } {
  199. if [info exists oldexec] {
  200. remote_file build delete $oldexec
  201. }
  202. set oldexec $execname
  203. }
  204. set execname "${executable}${count}"
  205. incr count
  206. # torture_{compile,execute}_xfail are set by the .x script
  207. # (if present)
  208. if [info exists torture_compile_xfail] {
  209. setup_xfail $torture_compile_xfail
  210. }
  211. # torture_execute_before_{compile,execute} can be set by the .x script
  212. # (if present)
  213. if [info exists torture_eval_before_compile] {
  214. set ignore_me [eval $torture_eval_before_compile]
  215. }
  216. remote_file build delete $execname
  217. verbose "Testing $testcase, $option" 1
  218. set options ""
  219. lappend options "additional_flags=-w $option"
  220. if { $additional_flags != "" } {
  221. lappend options "additional_flags=$additional_flags"
  222. }
  223. set comp_output [objc_target_compile "$src" "${execname}" executable $options]
  224. if ![objc_check_compile "$testcase compilation" $option $execname $comp_output] {
  225. unresolved "$testcase execution, $option"
  226. remote_file build delete $execname
  227. continue
  228. }
  229. # See if this source file uses "long long" types, if it does, and
  230. # no_long_long is set, skip execution of the test.
  231. if [target_info exists no_long_long] then {
  232. if [expr [search_for $src "long long"]] then {
  233. unsupported "$testcase execution, $option"
  234. remote_file build delete $execname
  235. continue
  236. }
  237. }
  238. if [info exists torture_execute_xfail] {
  239. setup_xfail $torture_execute_xfail
  240. }
  241. if [info exists torture_eval_before_execute] {
  242. set ignore_me [eval $torture_eval_before_execute]
  243. }
  244. # Sometimes we end up creating identical executables for two
  245. # consecutive sets of different of compiler options.
  246. #
  247. # In such cases we know the result of this test will be identical
  248. # to the result of the last test.
  249. #
  250. # So in cases where the time to load and run/simulate the test
  251. # is relatively high, compare the two binaries and avoid rerunning
  252. # tests if the executables are identical.
  253. #
  254. # Do not do this for native testing since the cost to load/execute
  255. # the test is fairly small and the comparison step actually slows
  256. # the entire process down because it usually does not "hit".
  257. set skip 0
  258. if { ![isnative] && [info exists oldexec] } {
  259. if { [remote_file build cmp $oldexec $execname] == 0 } {
  260. set skip 1
  261. set status $oldstatus
  262. }
  263. }
  264. if { $skip == 0 } {
  265. set result [objc_load "$execname" "" ""]
  266. set status [lindex $result 0]
  267. set output [lindex $result 1]
  268. }
  269. $status "$testcase execution, $option"
  270. set oldstatus $status
  271. # for each option
  272. }
  273. # tidy up
  274. if [info exists execname] {
  275. remote_file build delete $execname
  276. }
  277. if [info exists oldexec] {
  278. remote_file build delete $oldexec
  279. }
  280. }
  281. #
  282. # search_for -- looks for a string match in a file
  283. #
  284. proc search_for { file pattern } {
  285. set fd [open $file r]
  286. while { [gets $fd cur_line]>=0 } {
  287. if [string match "*$pattern*" $cur_line] then {
  288. close $fd
  289. return 1
  290. }
  291. }
  292. close $fd
  293. return 0
  294. }
  295. #
  296. # objc-torture -- the objc-torture testcase source file processor
  297. #
  298. # This runs compilation only tests (no execute tests).
  299. # SRC is the full pathname of the testcase, or just a file name in which case
  300. # we prepend $srcdir/$subdir.
  301. #
  302. # If the testcase has an associated .x file, we source that to run the
  303. # test instead. We use .x so that we don't lengthen the existing filename
  304. # to more than 14 chars.
  305. #
  306. proc objc-torture { args } {
  307. global srcdir subdir compiler_conditional_xfail_data
  308. set src [lindex $args 0]
  309. if { [llength $args] > 1 } {
  310. set options [lindex $args 1]
  311. } else {
  312. set options ""
  313. }
  314. # Prepend $srdir/$subdir if missing.
  315. if ![string match "*/*" $src] {
  316. set src "$srcdir/$subdir/$src"
  317. }
  318. # Check for alternate driver.
  319. if [file exists [file rootname $src].x] {
  320. verbose "Using alternate driver [file rootname [file tail $src]].x" 2
  321. set done_p 0
  322. catch "set done_p \[source [file rootname $src].x\]"
  323. if { $done_p } {
  324. return
  325. }
  326. }
  327. # Look for a loop within the source code - if we don't find one,
  328. # don't pass -funroll[-all]-loops.
  329. global torture_with_loops torture_without_loops
  330. if [expr [search_for $src "for*("]+[search_for $src "while*("]] then {
  331. set option_list $torture_with_loops
  332. } else {
  333. set option_list $torture_without_loops
  334. }
  335. # loop through all the options
  336. foreach option $option_list {
  337. # torture_compile_xfail is set by the .x script (if present)
  338. if [info exists torture_compile_xfail] {
  339. setup_xfail $torture_compile_xfail
  340. }
  341. # torture_execute_before_compile is set by the .x script (if present)
  342. if [info exists torture_eval_before_compile] {
  343. set ignore_me [eval $torture_eval_before_compile]
  344. }
  345. objc-torture-compile $src "$option $options"
  346. }
  347. }