1#
2# SPDX-License-Identifier: BSD-3-Clause
3#
4# Copyright © 2019 Keith Packard
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12#
13# 2. Redistributions in binary form must reproduce the above
14#    copyright notice, this list of conditions and the following
15#    disclaimer in the documentation and/or other materials provided
16#    with the distribution.
17#
18# 3. Neither the name of the copyright holder nor the names of its
19#    contributors may be used to endorse or promote products derived
20#    from this software without specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33# OF THE POSSIBILITY OF SUCH DAMAGE.
34#
35
36plain_tests_common = ['regex', 'ungetc',
37	              'malloc',
38	              'ffs', 'setjmp', 'atexit', 'on_exit',
39	              'timegm',
40                      'test-strchr',
41	              'test-memset', 'test-put',
42	              'test-raise',
43                      'test-sprintf-percent-n',
44                      'test-ctype',
45	      ]
46
47math_tests_common = [
48  'fenv',
49  'rand',
50  'test-efcvt',
51  'test-fma',
52  'test-strtod',
53]
54
55if have_attr_ctor_dtor
56  plain_tests_common += 'constructor'
57endif
58
59if have_complex
60  math_tests_common += 'complex-funcs'
61endif
62
63if newlib_nano_malloc or tests_enable_full_malloc_stress
64  math_tests_common += 'malloc_stress'
65endif
66
67if tinystdio
68  plain_tests_common += [
69    't_fmemopen',
70    'test-vfscanf-percent-a',
71  ]
72endif
73
74if atomic_ungetc or atomic_signal
75  plain_tests_common += 'test-atomic'
76endif
77
78if (posix_io or not tinystdio) and tests_enable_posix_io
79  plain_tests_common += ['posix-io']
80
81  # legacy stdio doesn't work on semihosting, so just skip it
82  if tinystdio
83    plain_tests_common += ['test-fopen',
84                    'test-mktemp',
85                    'test-tmpnam',
86                    'test-fread-fwrite',
87                    'test-ungetc-ftell',
88                    'test-fgetc',
89                    'test-fgets-eof',
90                    'test-wchar',
91                   ]
92  endif
93endif
94
95math_tests = math_tests_common + [
96  'math-funcs',
97]
98
99plain_tests = plain_tests_common
100
101plain_tests += math_tests + [
102  'test-funopen',
103  'time-tests',
104  'tls',
105]
106
107if tests_enable_stack_protector
108  plain_tests += 'stack-smash'
109endif
110
111plain_tests_native = plain_tests_common
112
113math_tests_native = math_tests_common
114foreach target : targets
115  value = get_variable('target_' + target)
116
117  _libs = [get_variable('lib_c' + target)]
118  if is_variable('lib_semihost' + target)
119    _libs += [get_variable('lib_semihost' + target)]
120  endif
121
122  _lib_files=[]
123  foreach _lib : _libs
124    _lib_files += _lib.full_path()
125  endforeach
126
127  if is_variable('crt0_semihost' + target)
128    _objs = [get_variable('crt0_semihost'+ target)]
129  elif is_variable('crt0_hosted' + target)
130    _objs = [get_variable('crt0_hosted'+ target)]
131  else
132    _objs = []
133  endif
134
135  _c_args = value[1] + get_variable('test_c_args_' + target, test_c_args)
136  _link_args = value[1] + _lib_files + get_variable('test_link_args_' + target, test_link_args)
137  _link_depends = get_variable('test_link_depends_' + target, test_link_depends) + _libs
138  if have_cplusplus
139    _cpp_args = value[1] + get_variable('test_cpp_args_' + target, test_cpp_args)
140  endif
141
142  t1 = 'printf_scanf'
143  if target == ''
144    t1_name = t1
145  else
146    t1_name = t1 + '_' + target
147  endif
148
149  test(t1_name,
150       executable(t1_name, ['printf_scanf.c', 'lock-valid.c'],
151		  c_args: double_printf_compile_args + _c_args,
152		  link_args: double_printf_link_args + _link_args,
153		  objects: _objs,
154		  link_depends:  _link_depends + _libs,
155		  include_directories: inc),
156       depends: bios_bin,
157       env: test_env)
158
159  t1 = 'printff_scanff'
160  if target == ''
161    t1_name = t1
162  else
163    t1_name = t1 + '_' + target
164  endif
165
166  test(t1_name,
167       executable(t1_name, ['printf_scanf.c', 'lock-valid.c'],
168		  c_args: float_printf_compile_args + _c_args,
169		  link_args: float_printf_link_args + _link_args,
170		  objects: _objs,
171		  link_depends:  _link_depends + _libs,
172		  include_directories: inc),
173       depends: bios_bin,
174       env: test_env)
175
176  t1 = 'printfl_scanfl'
177  if target == ''
178    t1_name = t1
179  else
180    t1_name = t1 + '_' + target
181  endif
182
183  test(t1_name,
184       executable(t1_name, ['printf_scanf.c', 'lock-valid.c'],
185		  c_args: llong_printf_compile_args + _c_args,
186		  link_args: llong_printf_link_args + _link_args,
187		  objects: _objs,
188		  link_depends:  _link_depends + _libs,
189		  include_directories: inc),
190       depends: bios_bin,
191       env: test_env)
192
193  t1 = 'printfi_scanfi'
194  if target == ''
195    t1_name = t1
196  else
197    t1_name = t1 + '_' + target
198  endif
199
200  test(t1_name,
201       executable(t1_name, ['printf_scanf.c', 'lock-valid.c'],
202		  c_args: int_printf_compile_args + _c_args,
203		  link_args: int_printf_link_args + _link_args,
204		  objects: _objs,
205		  link_depends:  _link_depends + _libs,
206		  include_directories: inc),
207       depends: bios_bin,
208       env: test_env)
209
210  t1 = 'printfm_scanfm'
211  if target == ''
212    t1_name = t1
213  else
214    t1_name = t1 + '_' + target
215  endif
216
217  test(t1_name,
218       executable(t1_name, ['printf_scanf.c', 'lock-valid.c'],
219		  c_args: min_printf_compile_args + _c_args,
220		  link_args: min_printf_link_args + _link_args,
221		  objects: _objs,
222		  link_depends:  _link_depends + _libs,
223		  include_directories: inc),
224       depends: bios_bin,
225       env: test_env)
226
227  t1 = 'printf-tests'
228  if target == ''
229    t1_name = t1
230  else
231    t1_name = t1 + '_' + target
232  endif
233
234  test(t1_name,
235       executable(t1_name, ['printf-tests.c', 'lock-valid.c'],
236		  c_args: double_printf_compile_args + _c_args,
237		  link_args: double_printf_link_args + _link_args,
238		  objects: _objs,
239		  link_depends:  _link_depends + _libs,
240		  include_directories: inc),
241       depends: bios_bin,
242       env: test_env)
243
244  t1 = 'printff-tests'
245  if target == ''
246    t1_name = t1
247  else
248    t1_name = t1 + '_' + target
249  endif
250
251  test(t1_name,
252       executable(t1_name, ['printf-tests.c', 'lock-valid.c'],
253		  c_args: float_printf_compile_args + _c_args,
254		  link_args: float_printf_link_args + _link_args,
255		  objects: _objs,
256		  link_depends:  _link_depends + _libs,
257		  include_directories: inc),
258       depends: bios_bin,
259       env: test_env)
260
261  t1 = 'printfi-tests'
262  if target == ''
263    t1_name = t1
264  else
265    t1_name = t1 + '_' + target
266  endif
267
268  test(t1_name,
269       executable(t1_name, ['printf-tests.c', 'lock-valid.c'],
270		  c_args: int_printf_compile_args + _c_args,
271		  link_args: int_printf_link_args + _link_args,
272		  objects: _objs,
273		  link_depends:  _link_depends + _libs,
274		  include_directories: inc),
275       depends: bios_bin,
276       env: test_env)
277
278  t1 = 'printfm-tests'
279  if target == ''
280    t1_name = t1
281  else
282    t1_name = t1 + '_' + target
283  endif
284
285  test(t1_name,
286       executable(t1_name, ['printf-tests.c', 'lock-valid.c'],
287		  c_args: min_printf_compile_args + _c_args,
288		  link_args: min_printf_link_args + _link_args,
289		  objects: _objs,
290		  link_depends:  _link_depends + _libs,
291		  include_directories: inc),
292       depends: bios_bin,
293       env: test_env)
294
295  t1 = 'try-ilp32'
296  if target == ''
297    t1_name = t1
298  else
299    t1_name = t1 + '_' + target
300  endif
301
302  t1 = 'time-sprintf'
303  if target == ''
304    t1_name = t1
305  else
306    t1_name = t1 + '_' + target
307  endif
308
309  test(t1_name,
310       executable(t1_name, ['time-sprintf.c', 'lock-valid.c'],
311		  c_args: int_printf_compile_args + _c_args + ['-fno-builtin'],
312		  link_args: int_printf_link_args + _link_args,
313		  objects: _objs,
314		  link_depends:  _link_depends + _libs,
315		  include_directories: inc),
316       depends: bios_bin,
317       env: test_env)
318
319  t1 = 'try-ilp32'
320  if target == ''
321    t1_name = t1
322  else
323    t1_name = t1 + '_' + target
324  endif
325
326  test(t1_name,
327       executable(t1_name, ['try-ilp32.c', 'try-ilp32-sub.c', 'lock-valid.c'],
328		  c_args: _c_args,
329		  link_args: _link_args,
330		  objects: _objs,
331		  link_depends:  _link_depends + _libs,
332		  include_directories: inc),
333       depends: bios_bin,
334       env: test_env)
335
336  t1 = 'hosted-exit'
337  if target == ''
338    t1_name = t1
339    t1_fail_name = t1 + '-fail'
340  else
341    t1_name = t1 + '_' + target
342    t1_fail_name = t1 + '-fail_' + target
343  endif
344
345  test(t1_name,
346       executable(t1_name, ['hosted-exit.c', 'lock-valid.c'],
347		  c_args: _c_args,
348		  link_args:  _link_args,
349		  objects: _objs,
350		  link_depends:  _link_depends + _libs,
351		  include_directories: inc),
352       depends: bios_bin,
353       env: test_env)
354
355  test(t1_fail_name,
356       executable(t1_fail_name, ['hosted-exit.c', 'lock-valid.c'],
357		  c_args: _c_args + ['-DRETVAL=1'],
358		  link_args:  _link_args,
359		  objects: _objs,
360		  link_depends:  _link_depends + _libs,
361		  include_directories: inc),
362       depends: bios_bin,
363       env: test_env,
364       should_fail: true
365      )
366
367  t1 = 'abort'
368  if target == ''
369    t1_name = t1
370  else
371    t1_name = t1 + '_' + target
372  endif
373
374  test(t1_name,
375       executable(t1_name, ['abort.c', 'lock-valid.c'],
376		  c_args: _c_args,
377		  link_args:  _link_args,
378		  objects: _objs,
379		  link_depends:  _link_depends + _libs,
380		  include_directories: inc),
381       depends: bios_bin,
382       env: test_env,
383       should_fail: true
384      )
385
386  # POSIX console code requires a constructor to run, so
387  # it is incompatible with the minimal crt0 when using stdout
388  # (which lock-valid.c uses).
389
390  if is_variable('crt0_minimal' + target) and not posix_console
391    _objs_minimal = [get_variable('crt0_minimal'+ target)]
392    t1 = 'constructor-skip'
393    if target == ''
394      t1_name = t1
395    else
396      t1_name = t1 + '_' + target
397    endif
398
399    test(t1_name,
400	 executable(t1_name, ['constructor-skip.c', 'lock-valid.c'],
401		    c_args: _c_args,
402		    link_args:  _link_args,
403		    objects: _objs_minimal,
404		    link_depends:  _link_depends + _libs,
405		    include_directories: inc),
406         depends: bios_bin,
407	 env: test_env)
408  endif
409
410  t1 = 'math_errhandling'
411  if target == ''
412    t1_name = t1
413  else
414    t1_name = t1 + '_' + target
415  endif
416
417  test(t1_name,
418       executable(t1_name, ['math_errhandling.c'],
419		  c_args: arg_fnobuiltin + _c_args,
420		  link_args: _link_args,
421		  objects: _objs,
422		  link_depends:  _link_depends + _libs,
423		  include_directories: inc),
424       depends: bios_bin,
425       env: test_env)
426
427  t1 = 'rounding-mode'
428  if target == ''
429    t1_name = t1
430  else
431    t1_name = t1 + '_' + target
432  endif
433
434  test(t1_name,
435       executable(t1_name, ['rounding-mode.c', 'rounding-mode-sub.c'],
436		  c_args: arg_fnobuiltin + _c_args,
437		  link_args: _link_args,
438		  objects: _objs,
439		  link_depends:  _link_depends + _libs,
440		  include_directories: inc),
441       depends: bios_bin,
442       env: test_env)
443
444  t1 = 'test-except'
445  t1_src = t1 + '.c'
446  if target == ''
447    t1_name = t1
448  else
449    t1_name = t1 + '_' + target
450  endif
451
452  test(t1_name,
453       executable(t1_name, [t1_src, 'lock-valid.c'],
454		  c_args: double_printf_compile_args + arg_fnobuiltin + _c_args,
455		  link_args: double_printf_link_args + _link_args,
456		  objects: _objs,
457		  link_depends:  _link_depends + _libs,
458		  include_directories: inc),
459       depends: bios_bin,
460       env: test_env,
461       should_fail: true
462      )
463
464  t1 = 'long_double'
465  t1_src = t1 + '.c'
466  if target == ''
467    t1_name = t1
468  else
469    t1_name = t1 + '_' + target
470  endif
471
472  test(t1_name,
473       executable(t1_name, t1_src,
474		  c_args: double_printf_compile_args + _c_args,
475		  link_args: double_printf_link_args + _link_args,
476		  objects: _objs,
477		  link_depends:  _link_depends + _libs,
478		  include_directories: inc),
479       depends: bios_bin,
480       env: test_env,
481       timeout: 90,
482      )
483
484  if get_option('test-stdin')
485    t1 = 'test-gets'
486    t1_src = 'test-gets.c'
487    if target == ''
488      t1_name = t1
489    else
490      t1_name = t1 + '_' + target
491    endif
492
493    test_gets = executable(t1_name, t1_src,
494		           c_args: _c_args,
495		           link_args: _link_args,
496		           objects: _objs,
497		           link_depends:  _link_depends + _libs,
498		           include_directories: inc)
499
500    test(t1_name + '-success',
501         test_gets,
502         depends: bios_bin,
503         args: ['hi'],
504         env: test_env,
505         timeout: 90
506        )
507
508
509    test(t1_name + '-failure',
510         test_gets,
511         depends: bios_bin,
512         args: ['this is a long string that should overflow the buffer'],
513         env: test_env,
514         timeout: 90,
515         should_fail: true
516        )
517  endif
518
519  if have_ubsan
520    t1 = 'test-ubsan'
521    t1_src = t1 + '.c'
522    if target == ''
523      t1_name = t1
524    else
525      t1_name = t1 + '_' + target
526    endif
527
528    test_ubsan_flags = []
529    if sanitize_trap_on_error
530      test_ubsan_flags = ['-DSANITIZE_TRAP_ON_ERROR']
531    endif
532
533    test(t1_name,
534	 executable(t1_name, t1_src,
535		    c_args: c_sanitize_bounds_flags + _c_args + test_ubsan_flags,
536		    link_args: _link_args,
537		    objects: _objs,
538		    link_depends:  _link_depends + _libs,
539		    include_directories: inc),
540	 depends: bios_bin,
541	 env: test_env,
542	 should_fail: sanitize_trap_on_error
543	)
544  endif
545
546  t1 = 'test-long-longl'
547  if target == ''
548    t1_name = t1
549  else
550    t1_name = t1 + '_' + target
551  endif
552
553  test(t1_name,
554       executable(t1_name, ['test-long-long.c', 'lock-valid.c'],
555		  c_args: llong_printf_compile_args + _c_args,
556		  link_args: llong_printf_link_args + _link_args,
557		  objects: _objs,
558		  link_depends:  _link_depends + _libs,
559		  include_directories: inc),
560       depends: bios_bin,
561       timeout: 120,
562       priority: -1,
563       env: test_env)
564
565  t1 = 'test-long-long'
566  if target == ''
567    t1_name = t1
568  else
569    t1_name = t1 + '_' + target
570  endif
571
572  test(t1_name,
573       executable(t1_name, ['test-long-long.c', 'lock-valid.c'],
574		  c_args: double_printf_compile_args + _c_args,
575		  link_args: double_printf_link_args + _link_args,
576		  objects: _objs,
577		  link_depends:  _link_depends + _libs,
578		  include_directories: inc),
579       depends: bios_bin,
580       timeout: 120,
581       priority: -1,
582       env: test_env)
583
584  plain_tests = ['rand', 'regex', 'ungetc', 'fenv',
585		 'malloc', 'tls',
586		 'ffs', 'setjmp', 'atexit', 'on_exit',
587		 'math-funcs', 'timegm', 'time-tests',
588                 'test-strtod', 'test-strchr',
589		 'test-memset', 'test-put',
590		 'test-efcvt', 'test-atomic',
591		 'test-raise',
592                 'test-fma',
593                 'test-funopen',
594		]
595
596  if have_attr_ctor_dtor
597    plain_tests += 'constructor'
598  endif
599
600  if have_complex
601    plain_tests += 'complex-funcs'
602  endif
603
604  if newlib_nano_malloc or tests_enable_full_malloc_stress
605    plain_tests += 'malloc_stress'
606  endif
607
608  if tinystdio
609    plain_tests += 't_fmemopen'
610  endif
611
612  if (posix_io or not tinystdio) and tests_enable_posix_io
613    plain_tests += ['posix-io']
614
615    # legacy stdio doesn't work on semihosting, so just skip it
616    if tinystdio
617      plain_tests += ['test-fopen',
618                      'test-mktemp',
619                      'test-tmpnam',
620                      'test-fread-fwrite',
621                      'test-ungetc-ftell',
622                      'test-fgetc',
623                      'test-fgets-eof',
624                     ]
625    endif
626  endif
627
628  if tests_enable_stack_protector
629    plain_tests += 'stack-smash'
630  endif
631
632  plain_tests += ['test-memcpy_s',
633                  'test-memset_s',
634                  'test-memmove_s',
635                  'test-strcat_s',
636                  'test-strcpy_s',
637                  'test-strerror_s',
638                  'test-strerrorlen_s',
639                  'test-strncat_s',
640                  'test-strncpy_s',
641                  'test-strnlen_s',
642                  ]
643
644  if tinystdio
645    plain_tests += 'test-sprintf_s'
646  endif
647
648
649  foreach t1 : plain_tests
650    t1_src = t1 + '.c'
651    if target == ''
652      t1_name = t1
653    else
654      t1_name = t1 + '_' + target
655    endif
656    test_file_name_arg=['-DTEST_FILE_NAME="' + t1_name + '.txt"']
657
658    test(t1_name,
659	 executable(t1_name, [t1_src, 'lock-valid.c'],
660		    c_args: double_printf_compile_args + test_file_name_arg + _c_args,
661		    link_args: double_printf_link_args + _link_args,
662		    objects: _objs,
663		    link_depends:  _link_depends + _libs,
664		    include_directories: inc),
665         depends: bios_bin,
666	 timeout: 60,
667	 env: test_env)
668  endforeach
669
670  if have_cplusplus
671    t1 = 'test-cplusplus'
672    t1_src = t1 + '.cpp'
673    if target == ''
674      t1_name = t1
675    else
676      t1_name = t1 + '_' + target
677    endif
678    test(t1_name,
679         executable(t1_name, t1_src,
680                    cpp_args: _cpp_args,
681		    link_args: _cpp_args + _link_args,
682		    objects: _objs,
683		    link_depends:  _link_depends + _libs,
684                    include_directories: inc))
685  endif
686endforeach
687
688if enable_native_math_tests
689
690  native_lib_m = cc.find_library('m', required: false)
691
692  if native_lib_m.found()
693    test('long_double-native',
694	 executable('long_double-native', 'long_double.c',
695		    c_args: native_c_args,
696		    link_args: native_c_args,
697		    dependencies: native_lib_m))
698    test('math_errhandling-native',
699	 executable('math_errhandling-native', 'math_errhandling.c',
700		    c_args: native_c_args,
701		    link_args: native_c_args,
702		    dependencies: native_lib_m))
703    test('rounding-mode-native',
704	 executable('rounding-mode-native',
705		    ['rounding-mode.c', 'rounding-mode-sub.c'],
706		    c_args: native_c_args,
707		    link_args: native_c_args,
708		    dependencies: native_lib_m))
709    test('printf-tests-native',
710	 executable('printf-tests-native',
711		    'printf-tests.c',
712		    c_args: native_c_args,
713		    link_args: native_c_args,
714		    dependencies: native_lib_m))
715    test('printf_scanf-native',
716	 executable('printf_scanf-native',
717		    'printf_scanf.c',
718		    c_args: native_c_args,
719		    link_args: native_c_args,
720		    dependencies: native_lib_m))
721
722    foreach t1 : math_tests_native
723      t1_src = t1 + '.c'
724      t1_name = t1 + '-native'
725
726      test(t1_name,
727	   executable(t1_name, t1_src,
728		      c_args: native_c_args,
729		      link_args: native_c_args,
730                      dependencies: native_lib_m))
731    endforeach
732
733  endif
734
735
736endif
737
738if enable_native_tests
739
740  if have_cplusplus
741    test('test-cplusplus-native',
742         executable('test-cplusplus-native', 'test-cplusplus.cpp',
743                    cpp_args: native_cpp_args,
744		    link_args: native_cpp_args))
745  endif
746
747
748  foreach t1 : plain_tests_native
749    t1_src = t1 + '.c'
750    t1_name = t1 + '-native'
751    test_file_name_arg=['-DTEST_FILE_NAME="' + t1_name + '.txt"']
752
753    test(t1_name,
754	 executable(t1_name, t1_src,
755		    c_args: native_c_args,
756		    link_args: native_c_args))
757  endforeach
758
759endif
760
761subdir('libc-testsuite')
762
763if has_arm_semihost
764  subdir('semihost')
765endif
766