2 Code shared between multiple testcases.
4 This file contains "main" and support code.
5 Each testcase should implement the following hooks:
8 create_code (gcc_jit_context *ctxt, void * user_data);
10 and, #ifndef TEST_COMPILING_TO_FILE,
13 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result);
19 /* test-threads.c use threads, but dejagnu.h isn't thread-safe; there's a
20 shared "buffer", and the counts of passed/failed etc are globals.
22 The solution is to use macros to rename "pass" and "fail", replacing them
23 with mutex-guarded alternatives. */
24 #ifdef MAKE_DEJAGNU_H_THREADSAFE
25 #define pass dejagnu_pass
26 #define fail dejagnu_fail
27 #define note dejagnu_note
32 #ifdef MAKE_DEJAGNU_H_THREADSAFE
38 static char test
[1024];
40 #define CHECK_NON_NULL(PTR) \
44 pass ("%s: %s: %s is non-null", \
45 test, __func__, #PTR); \
49 fail ("%s: %s: %s is NULL", \
50 test, __func__, #PTR); \
55 #define CHECK_VALUE(ACTUAL, EXPECTED) \
57 if ((ACTUAL) == (EXPECTED)) \
59 pass ("%s: %s: actual: %s == expected: %s", \
60 test, __func__, #ACTUAL, #EXPECTED); \
64 fail ("%s: %s: actual: %s != expected: %s", \
65 test, __func__, #ACTUAL, #EXPECTED); \
66 fprintf (stderr, "incorrect value\n"); \
71 #define CHECK_DOUBLE_VALUE(ACTUAL, EXPECTED) \
73 double expected = (EXPECTED); \
74 double actual = (ACTUAL); \
75 if (abs (actual - expected) < 0.00001) \
77 pass ("%s: %s: actual: %s == expected: %s", \
78 __func__, test, #ACTUAL, #EXPECTED); \
82 fail ("%s: %s: actual: %s != expected: %s", \
83 __func__, test, #ACTUAL, #EXPECTED); \
84 fprintf (stderr, "incorrect value: %f\n", actual); \
89 #define CHECK_STRING_VALUE(ACTUAL, EXPECTED) \
90 check_string_value (__func__, (ACTUAL), (EXPECTED));
92 #define CHECK_STRING_STARTS_WITH(ACTUAL, EXPECTED_PREFIX) \
93 check_string_starts_with (__func__, (ACTUAL), (EXPECTED_PREFIX));
95 #define CHECK_STRING_CONTAINS(ACTUAL, EXPECTED_SUBSTRING) \
96 check_string_contains (__func__, #ACTUAL, (ACTUAL), (EXPECTED_SUBSTRING));
102 pass ("%s: %s: %s", test, __func__, #COND); \
106 fail ("%s: %s: %s", test, __func__, #COND); \
111 #define CHECK_NO_ERRORS(CTXT) \
113 const char *err = gcc_jit_context_get_first_error (CTXT); \
115 fail ("%s: %s: error unexpectedly occurred: %s", test, __func__, err); \
117 pass ("%s: %s: no errors occurred", test, __func__); \
120 /* Hooks that testcases should provide. */
122 create_code (gcc_jit_context
*ctxt
, void * user_data
);
124 #ifndef TEST_COMPILING_TO_FILE
126 verify_code (gcc_jit_context
*ctxt
, gcc_jit_result
*result
);
129 extern void check_string_value (const char *funcname
,
130 const char *actual
, const char *expected
);
133 check_string_starts_with (const char *funcname
,
135 const char *expected_prefix
);
138 check_string_contains (const char *funcname
,
141 const char *expected_substring
);
143 /* Implement framework needed for turning the testcase hooks into an
144 executable. test-combination.c and test-threads.c each combine multiple
145 testcases into larger testcases, so we have COMBINED_TEST as a way of
146 temporarily turning off this part of harness.h. */
147 #ifndef COMBINED_TEST
149 void check_string_value (const char *funcname
,
150 const char *actual
, const char *expected
)
152 if (actual
&& !expected
)
154 fail ("%s: %s: actual: \"%s\" != expected: NULL",
155 funcname
, test
, actual
);
156 fprintf (stderr
, "incorrect value\n");
159 if (expected
&& !actual
)
161 fail ("%s: %s: actual: NULL != expected: \"%s\"",
162 funcname
, test
, expected
);
163 fprintf (stderr
, "incorrect value\n");
166 if (actual
&& expected
)
168 if (strcmp (actual
, expected
))
170 fail ("%s: %s: actual: \"%s\" != expected: \"%s\"",
171 test
, funcname
, actual
, expected
);
172 fprintf (stderr
, "incorrect valuen");
175 pass ("%s: %s: actual: \"%s\" == expected: \"%s\"",
176 test
, funcname
, actual
, expected
);
179 pass ("%s: actual: NULL == expected: NULL");
183 check_string_starts_with (const char *funcname
,
185 const char *expected_prefix
)
189 fail ("%s: %s: actual: NULL != expected prefix: \"%s\"",
190 test
, funcname
, expected_prefix
);
191 fprintf (stderr
, "incorrect value\n");
195 if (strncmp (actual
, expected_prefix
, strlen (expected_prefix
)))
197 fail ("%s: %s: actual: \"%s\" did not begin with expected prefix: \"%s\"",
198 test
, funcname
, actual
, expected_prefix
);
199 fprintf (stderr
, "incorrect value\n");
203 pass ("%s: actual: \"%s\" begins with expected prefix: \"%s\"",
204 test
, actual
, expected_prefix
);
208 check_string_contains (const char *funcname
,
211 const char *expected_substring
)
215 fail ("%s: %s, %s: actual: NULL does not contain expected substring: \"%s\"",
216 test
, funcname
, name
, expected_substring
);
217 fprintf (stderr
, "incorrect value\n");
221 if (!strstr (actual
, expected_substring
))
223 fail ("%s: %s: %s: actual: \"%s\" did not contain expected substring: \"%s\"",
224 test
, funcname
, name
, actual
, expected_substring
);
225 fprintf (stderr
, "incorrect value\n");
229 pass ("%s: %s: %s: found substring: \"%s\"",
230 test
, funcname
, name
, expected_substring
);
233 #ifndef TEST_ESCHEWS_SET_OPTIONS
234 static void set_options (gcc_jit_context
*ctxt
, const char *argv0
)
236 /* Set up options. */
237 gcc_jit_context_set_str_option (
239 GCC_JIT_STR_OPTION_PROGNAME
,
241 gcc_jit_context_set_int_option (
243 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL
,
245 gcc_jit_context_set_bool_option (
247 GCC_JIT_BOOL_OPTION_DEBUGINFO
,
249 gcc_jit_context_set_bool_option (
251 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE
,
253 gcc_jit_context_set_bool_option (
255 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE
,
257 gcc_jit_context_set_bool_option (
259 GCC_JIT_BOOL_OPTION_SELFCHECK_GC
,
261 gcc_jit_context_set_bool_option (
263 GCC_JIT_BOOL_OPTION_DUMP_SUMMARY
,
266 #endif /* #ifndef TEST_ESCHEWS_SET_OPTIONS */
268 /* Concatenate two strings. The result must be released using "free". */
271 concat_strings (const char *prefix
, const char *suffix
)
273 char *result
= (char *)malloc (strlen (prefix
) + strlen (suffix
) + 1);
276 fail ("malloc failure");
279 strcpy (result
, prefix
);
280 strcpy (result
+ strlen (prefix
), suffix
);
281 result
[strlen (prefix
) + strlen (suffix
)] = '\0';
285 #ifndef TEST_ESCHEWS_TEST_JIT
286 /* Set up logging to a logfile of the form "test-FOO.exe.log.txt".
289 SRCDIR/gcc/testsuite/jit.dg/test-hello-world.c
291 BUILDDIR/gcc/testsuite/jit/test-hello-world.c.exe
293 BUILDDIR/gcc/testsuite/jit/test-hello-world.c.exe.log.txt
295 The logfile must be closed by the caller.
297 Note that not every testcase enables logging. */
299 set_up_logging (gcc_jit_context
*ctxt
, const char *argv0
)
301 const char *logfile_name_suffix
= ".log.txt";
302 char *logfile_name
= NULL
;
303 FILE *logfile
= NULL
;
305 /* Build a logfile name of the form "test-FOO.exe.log.txt". */
306 logfile_name
= concat_strings (argv0
, logfile_name_suffix
);
309 logfile
= fopen (logfile_name
, "w");
310 CHECK_NON_NULL (logfile
);
314 gcc_jit_context_set_logfile (ctxt
, logfile
, 0, 0);
319 /* Exercise the API entrypoint:
320 gcc_jit_context_dump_reproducer_to_file
321 by calling it on the context, using the path expected by jit.exp. */
323 dump_reproducer (gcc_jit_context
*ctxt
, const char *argv0
)
325 char *reproducer_name
;
326 reproducer_name
= concat_strings (argv0
, ".reproducer.c");
327 if (!reproducer_name
)
329 note ("%s: writing reproducer to %s", test
, reproducer_name
);
330 gcc_jit_context_dump_reproducer_to_file (ctxt
, reproducer_name
);
331 free (reproducer_name
);
334 /* Run one iteration of the test. */
336 test_jit (const char *argv0
, void *user_data
)
338 gcc_jit_context
*ctxt
;
340 #ifndef TEST_COMPILING_TO_FILE
341 gcc_jit_result
*result
;
344 #ifdef TEST_COMPILING_TO_FILE
345 unlink (OUTPUT_FILENAME
);
348 ctxt
= gcc_jit_context_acquire ();
351 fail ("gcc_jit_context_acquire failed");
355 logfile
= set_up_logging (ctxt
, argv0
);
357 set_options (ctxt
, argv0
);
359 create_code (ctxt
, user_data
);
361 dump_reproducer (ctxt
, argv0
);
363 #ifdef TEST_COMPILING_TO_FILE
364 gcc_jit_context_compile_to_file (ctxt
,
367 CHECK_NO_ERRORS (ctxt
);
368 #else /* #ifdef TEST_COMPILING_TO_FILE */
369 /* This actually calls into GCC and runs the build, all
370 in a mutex for now. */
371 result
= gcc_jit_context_compile (ctxt
);
373 verify_code (ctxt
, result
);
376 gcc_jit_context_release (ctxt
);
378 #ifndef TEST_COMPILING_TO_FILE
379 /* Once we're done with the code, this unloads the built .so file: */
380 gcc_jit_result_release (result
);
386 #endif /* #ifndef TEST_ESCHEWS_TEST_JIT */
388 /* We want to prefix all unit test results with the test, but dejagnu.exp's
389 host_execute appears to get confused by the leading "./" of argv0,
390 leading to all tests simply reporting as a single period character ".".
392 Hence strip out the final component of the path to the program name,
393 so that we can use that in unittest reports. */
395 extract_progname (const char *argv0
)
399 p
= argv0
+ strlen (argv0
);
400 while (p
!= argv0
&& p
[-1] != '/')
405 #ifndef TEST_PROVIDES_MAIN
407 main (int argc
, char **argv
)
411 for (i
= 1; i
<= 5; i
++)
413 snprintf (test
, sizeof (test
),
414 "%s iteration %d of %d",
415 extract_progname (argv
[0]),
418 //printf ("ITERATION %d\n", i);
419 test_jit (argv
[0], NULL
);
427 #endif /* #ifndef TEST_PROVIDES_MAIN */
429 #endif /* #ifndef COMBINED_TEST */