diff --git a/lib/json/cJSON.c b/lib/json/cJSON.c index 1fb017821..c73656851 100644 --- a/lib/json/cJSON.c +++ b/lib/json/cJSON.c @@ -353,8 +353,8 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu loop_end: number_c_string[i] = '\0'; - output = (unsigned char*)input_buffer->hooks.allocate(i * sizeof(char)); - memcpy(output, number_c_string, i); + output = (unsigned char*)input_buffer->hooks.allocate(i * sizeof(char) + 1); + memcpy(output, number_c_string, i + 1); number = strtod((const char*)number_c_string, (char**)&after_end); if (number_c_string == after_end) diff --git a/lib/json/sail_config.c b/lib/json/sail_config.c index 6ba17e307..343b9b6bc 100644 --- a/lib/json/sail_config.c +++ b/lib/json/sail_config.c @@ -75,7 +75,7 @@ void sail_config_set_file(const char *path) void sail_config_cleanup(void) { - sail_free(sail_config); + cJSON_Delete((cJSON *)sail_config); } sail_config_json sail_config_get(size_t n, const char *key[]) @@ -196,7 +196,9 @@ void sail_config_unwrap_string(sail_string *str, const sail_config_json config) void sail_config_unwrap_int(sail_int *n, const sail_config_json config) { cJSON *json = (cJSON *)config; - mpz_set_str(*n, json->valuestring, 10); + if (mpz_set_str(*n, json->valuestring, 10) == -1) { + sail_assert(false, "Failed to parse integer from configuration"); + } } void sail_config_truncate(lbits *rop) { @@ -207,6 +209,8 @@ void sail_config_truncate(lbits *rop) { mpz_mul_2exp(tmp, tmp, rop->len); mpz_sub_ui(tmp, tmp, 1); mpz_and(*rop->bits, *rop->bits, tmp); + + mpz_clear(tmp); } void sail_config_unwrap_bits(lbits *bv, const sail_config_json config) diff --git a/test/c/config_int.sail b/test/c/config_int.sail index 1bc48d8d1..861a93960 100644 --- a/test/c/config_int.sail +++ b/test/c/config_int.sail @@ -9,6 +9,8 @@ $else $option --config ../c/config_int.json $endif +$option --sv-int-size 256 + val main : unit -> unit function main() = { diff --git a/test/c/run_tests.py b/test/c/run_tests.py index 10b594780..ebe66aabd 100755 --- a/test/c/run_tests.py +++ b/test/c/run_tests.py @@ -43,12 +43,15 @@ def test_c(name, c_opts, sail_opts, valgrind, compiler='cc'): c_opts += ' \'{}\'/lib/json/*.c -I \'{}\'/lib/json'.format(sail_dir, sail_dir) step('\'{}\' -no_warn -c {} {} 1> {}.c'.format(sail, sail_opts, filename, basename)) step('{} {} {}.c \'{}\'/lib/*.c -lgmp -I \'{}\'/lib -o {}.bin'.format(compiler, c_opts, basename, sail_dir, sail_dir, basename)) - step('./{}.bin > {}.result 2> {}.err_result'.format(basename, basename, basename), expected_status = 1 if basename.startswith('fail') else 0) + step('./{}.bin > {}.result 2> {}.err_result'.format(basename, basename, basename), + expected_status = 1 if basename.startswith('fail') else 0, + stderr_file='{}.err_result'.format(basename)) step('diff {}.result {}.expect'.format(basename, basename)) if os.path.exists('{}.err_expect'.format(basename)): step('diff {}.err_result {}.err_expect'.format(basename, basename)) if valgrind and not basename.startswith('fail'): - step("valgrind --leak-check=full --track-origins=yes --errors-for-leak-kinds=all --error-exitcode=2 ./{}.bin".format(basename), expected_status = 1 if basename.startswith('fail') else 0) + step("valgrind --leak-check=full --track-origins=yes --errors-for-leak-kinds=all --error-exitcode=2 ./{}.bin".format(basename), + expected_status = 1 if basename.startswith('fail') else 0) step('rm {}.c {}.bin {}.result'.format(basename, basename, basename)) print_ok(filename) sys.exit() @@ -221,6 +224,7 @@ def test_coq(name): xml += test_c('constant folding', '', '-Oconstant_fold', False) #xml += test_c('monomorphised C', '-O2', '-O -Oconstant_fold -auto_mono', True) xml += test_c('undefined behavior sanitised', '-O2 -fsanitize=undefined', '-O', False) + xml += test_c('address sanitised', '-O2 -fsanitize=address -g', '-O', False) if 'cpp' in targets: xml += test_c('unoptimized C with C++ compiler', '-xc++', '', False, compiler='c++') diff --git a/test/sailtest.py b/test/sailtest.py index eb6c1fc8c..1c802840b 100644 --- a/test/sailtest.py +++ b/test/sailtest.py @@ -9,6 +9,7 @@ parser.add_argument("--hide-error-output", help="Hide error information.", action='store_true') parser.add_argument("--compact", help="Compact output.", action='store_true') parser.add_argument("--targets", help="Targets to use (where supported).", action='append') +parser.add_argument("--test", help="Run only specified test.", action='append') args = parser.parse_args() def is_compact(): @@ -81,7 +82,8 @@ def chunks(filenames, cores): ys = [] chunk = [] for filename in filenames: - if re.match('.+\.sail$', filename): + basename = os.path.splitext(os.path.basename(filename))[0] + if re.match('.+\.sail$', filename) and (not args.test or basename in args.test): chunk.append(filename) if len(chunk) >= cores: ys.append(list(chunk)) @@ -113,7 +115,7 @@ def project_chunks(filenames, cores): ys.append(list(chunk)) return ys -def step(string, expected_status=0): +def step(string, expected_status=0, stderr_file=''): p = subprocess.Popen(string, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) out, err = p.communicate() status = p.wait() @@ -127,7 +129,14 @@ def step(string, expected_status=0): print(out.decode('utf-8')) print('{}stderr{}:'.format(color.NOTICE, color.END)) print(err.decode('utf-8')) - sys.exit(1) + if stderr_file != '': + try: + with open(stderr_file, 'r') as file: + content = file.read() + print('{}stderr file{}:'.format(color.NOTICE, color.END)) + print(content) + except FileNotFoundError: + print('File {} not found'.format(stderr_file)) def banner(string): print('-' * len(string))