Skip to content

Commit

Permalink
Change default exit severity to FAILURE
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Jun 4, 2023
1 parent 5a4ce46 commit 63a8319
Show file tree
Hide file tree
Showing 17 changed files with 118 additions and 44 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
- Added support for the new `'designated_subtype` and `'index`
attributes in VHDL-2019.
- Implemented the date/time functions from `std.env` in VHDL-2019.
- The default exit severity was changed from `error` to `failure`. This
means a failing assertion no longer immediately terminates the
simulation. The old behaviour can be restored with
`--exit-severity=error`.

## Version 1.9.2 - 2023-05-01
- Fix elaboration errors with recursive entity instantiation (#668).
Expand Down
21 changes: 13 additions & 8 deletions src/diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ typedef struct _hint_rec {
} hint_rec_t;

static unsigned n_errors = 0;
static unsigned error_limit = 0;
static file_list_t loc_files;
static vhdl_severity_t exit_severity = SEVERITY_ERROR;
static vhdl_severity_t exit_severity = SEVERITY_FAILURE;
static diag_level_t stderr_level = DIAG_DEBUG;
static nvc_lock_t diag_lock = 0;

Expand Down Expand Up @@ -952,7 +953,7 @@ void diag_femit(diag_t *d, FILE *f)
const bool is_error = d->level >= DIAG_ERROR
|| (opt_get_int(OPT_UNIT_TEST) && d->level > DIAG_DEBUG);

if (is_error && relaxed_add(&n_errors, 1) == opt_get_int(OPT_ERROR_LIMIT))
if (is_error && relaxed_add(&n_errors, 1) == error_limit)
fatal("too many errors, giving up");

for (int i = 0; i < d->hints.count; i++)
Expand Down Expand Up @@ -1069,6 +1070,13 @@ void reset_error_count(void)
n_errors = 0;
}

unsigned set_error_limit(unsigned limit)
{
const unsigned old = error_limit;
error_limit = limit;
return old;
}

void fmt_loc(FILE *f, const loc_t *loc)
{
// Legacy interface for debugging only
Expand All @@ -1094,14 +1102,11 @@ diag_level_t diag_severity(vhdl_severity_t severity)
return DIAG_ERROR;
}

void set_exit_severity(vhdl_severity_t severity)
vhdl_severity_t set_exit_severity(vhdl_severity_t severity)
{
const vhdl_severity_t old = exit_severity;
exit_severity = severity;
}

vhdl_severity_t get_exit_severity(void)
{
return exit_severity;
return old;
}

void set_stderr_severity(vhdl_severity_t severity)
Expand Down
4 changes: 2 additions & 2 deletions src/diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ void diag_stacktrace(diag_t *d, bool stacktrace);

unsigned error_count(void);
void reset_error_count(void);
unsigned set_error_limit(unsigned limit);

void wrapped_printf(const char *fmt, ...);

Expand All @@ -124,9 +125,8 @@ typedef enum {
} vhdl_severity_t;

// Conversion from VHDL severity
void set_exit_severity(vhdl_severity_t severity);
vhdl_severity_t set_exit_severity(vhdl_severity_t severity);
void set_stderr_severity(vhdl_severity_t severity);
diag_level_t diag_severity(vhdl_severity_t severity);
vhdl_severity_t get_exit_severity(void);

#endif // _DIAG_H
33 changes: 22 additions & 11 deletions src/jit/jit-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ static void jit_oom_cb(mspace_t *m, size_t size)
heapsize, MAX(1, (heapsize * 2) / 1024 / 1024));

diag_emit(d);
jit_abort(EXIT_FAILURE);
jit_abort_with_status(EXIT_FAILURE);
}

jit_thread_local_t *jit_thread_local(void)
Expand Down Expand Up @@ -640,7 +640,6 @@ bool jit_fastcall(jit_t *j, jit_handle_t handle, jit_scalar_t *result,
jit_transition(j, JIT_RUNNING, JIT_IDLE);
thread->jmp_buf_valid = 0;
thread->anchor = NULL;
atomic_cas(&(j->exit_status), 0, rc - 1);
return false;
}
}
Expand All @@ -662,10 +661,8 @@ static bool jit_try_vcall(jit_t *j, jit_func_t *f, jit_scalar_t *result,

*result = args[0];
}
else {
atomic_cas(&(j->exit_status), 0, rc - 1);
else
failed = true;
}

jit_transition(j, JIT_RUNNING, oldstate);
thread->jmp_buf_valid = 0;
Expand Down Expand Up @@ -1030,21 +1027,22 @@ void jit_msg(const loc_t *where, diag_level_t level, const char *fmt, ...)
diag_emit(d);

if (level == DIAG_FATAL)
jit_abort(EXIT_FAILURE);
jit_abort_with_status(EXIT_FAILURE);
}

void jit_abort(int code)
void jit_abort(void)
{
jit_thread_local_t *thread = jit_thread_local();

const int code = atomic_load(&thread->jit->exit_status);

switch (thread->state) {
case JIT_IDLE:
fatal_exit(code);
break;
case JIT_RUNNING:
assert(code >= 0);
if (thread->jmp_buf_valid)
siglongjmp(thread->abort_env, code + 1);
siglongjmp(thread->abort_env, 1);
else
fatal_exit(code);
break;
Expand All @@ -1053,9 +1051,22 @@ void jit_abort(int code)
__builtin_unreachable();
}

void jit_reset_exit_status(jit_t *j)
void jit_abort_with_status(int code)
{
jit_thread_local_t *thread = jit_thread_local();
atomic_store(&(thread->jit->exit_status), code);

jit_abort();
}

void jit_set_exit_status(jit_t *j, int status)
{
atomic_cas(&(j->exit_status), 0, status);
}

void jit_reset_exit_status(jit_t *j, int status)
{
atomic_store(&(j->exit_status), 0);
atomic_store(&(j->exit_status), status);
}

int jit_exit_status(jit_t *j)
Expand Down
8 changes: 6 additions & 2 deletions src/jit/jit-exits.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,9 @@ void x_report(const uint8_t *msg, int32_t msg_len, int8_t severity,
diag_emit(d);

if (level == DIAG_FATAL)
jit_abort(EXIT_FAILURE);
jit_abort_with_status(EXIT_FAILURE);
else if (level >= DIAG_ERROR)
jit_set_exit_status(jit_thread_local()->jit, EXIT_FAILURE);
}

void x_assert_fail(const uint8_t *msg, int32_t msg_len, int8_t severity,
Expand Down Expand Up @@ -497,7 +499,9 @@ void x_assert_fail(const uint8_t *msg, int32_t msg_len, int8_t severity,
diag_emit(d);

if (level == DIAG_FATAL)
jit_abort(EXIT_FAILURE);
jit_abort_with_status(EXIT_FAILURE);
else if (level >= DIAG_ERROR)
jit_set_exit_status(jit_thread_local()->jit, EXIT_FAILURE);
}

void x_elab_order_fail(tree_t where)
Expand Down
1 change: 1 addition & 0 deletions src/jit/jit-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ jit_thread_local_t *jit_thread_local(void);
void jit_fill_irbuf(jit_func_t *f);
int32_t *jit_get_cover_ptr(jit_t *j, jit_value_t addr);
object_t *jit_get_locus(jit_value_t value);
void jit_set_exit_status(jit_t *j, int status);

jit_cfg_t *jit_get_cfg(jit_func_t *f);
void jit_free_cfg(jit_func_t *f);
Expand Down
7 changes: 5 additions & 2 deletions src/jit/jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ mspace_t *jit_get_mspace(jit_t *j);
void jit_load_dll(jit_t *j, ident_t name);
void jit_preload(jit_t *j);
int jit_exit_status(jit_t *j);
void jit_reset_exit_status(jit_t *j);
void jit_reset_exit_status(jit_t *j, int status);
void jit_add_tier(jit_t *j, int threshold, const jit_plugin_t *plugin);
ident_t jit_get_name(jit_t *j, jit_handle_t handle);
void jit_register_native_plugin(jit_t *j);
Expand Down Expand Up @@ -123,6 +123,9 @@ __attribute__((format(printf, 3, 4)))
void jit_msg(const loc_t *where, diag_level_t level, const char *fmt, ...);

__attribute__((noreturn))
void jit_abort(int code);
void jit_abort(void);

__attribute__((noreturn))
void jit_abort_with_status(int code);

#endif // _JIT_H
7 changes: 5 additions & 2 deletions src/nvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static int analyse(int argc, char **argv)
};

const int next_cmd = scan_cmd(2, argc, argv);
int c, index = 0;
int c, index = 0, error_limit = 20;
const char *spec = ":D:";

while ((c = getopt_long(next_cmd, argv, spec, long_options, &index)) != -1) {
Expand All @@ -159,7 +159,7 @@ static int analyse(int argc, char **argv)
opt_set_int(OPT_RELAXED, 1);
break;
case 'l':
opt_set_int(OPT_ERROR_LIMIT, parse_int(optarg));
error_limit = parse_int(optarg);
break;
case 'P':
opt_set_int(OPT_PSL_COMMENTS, 1);
Expand All @@ -175,6 +175,8 @@ static int analyse(int argc, char **argv)
}
}

set_error_limit(error_limit);

lib_t work = lib_work();
jit_t *jit = jit_new();

Expand All @@ -193,6 +195,7 @@ static int analyse(int argc, char **argv)
}

jit_free(jit);
set_error_limit(0);

if (error_count() > 0)
return EXIT_FAILURE;
Expand Down
1 change: 0 additions & 1 deletion src/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ void set_default_options(void)
opt_set_str(OPT_EVAL_VERBOSE, getenv("NVC_EVAL_VERBOSE"));
opt_set_str(OPT_ELAB_VERBOSE, getenv("NVC_ELAB_VERBOSE"));
opt_set_size(OPT_HEAP_SIZE, 16 * 1024 * 1024);
opt_set_int(OPT_ERROR_LIMIT, 20);
opt_set_int(OPT_GC_STRESS, 0 DEBUG_ONLY(|| get_int_env("NVC_GC_STRESS", 0)));
opt_set_int(OPT_RELAXED, 0);
opt_set_str(OPT_JIT_VERBOSE, getenv("NVC_JIT_VERBOSE"));
Expand Down
1 change: 0 additions & 1 deletion src/option.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <stdbool.h>

typedef enum {
OPT_ERROR_LIMIT,
OPT_RT_STATS,
OPT_VHPI_TRACE,
OPT_DUMP_LLVM,
Expand Down
8 changes: 4 additions & 4 deletions src/rt/model.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,8 +1105,7 @@ static res_memo_t *memo_resolution_fn(rt_model_t *m, rt_signal_t *signal,
if (nlits == 0 || nlits > 16)
return memo;

const vhdl_severity_t old_severity = get_exit_severity();
set_exit_severity(SEVERITY_NOTE);
const vhdl_severity_t old_severity = set_exit_severity(SEVERITY_NOTE);

jit_set_silent(m->jit, true);

Expand Down Expand Up @@ -1149,7 +1148,7 @@ static res_memo_t *memo_resolution_fn(rt_model_t *m, rt_signal_t *signal,
type_pp(tree_type(signal->where)));

jit_set_silent(m->jit, false);
jit_reset_exit_status(m->jit);
jit_reset_exit_status(m->jit, 0);

set_exit_severity(old_severity);

Expand Down Expand Up @@ -2908,7 +2907,8 @@ static void reached_iteration_limit(rt_model_t *m)
diag_hint(d, NULL, "you can increase this limit with $bold$--stop-delta$$");
diag_emit(d);

jit_abort(EXIT_FAILURE);
jit_reset_exit_status(m->jit, EXIT_FAILURE);
m->force_stop = true;
}

static void sync_event_cache(rt_model_t *m)
Expand Down
10 changes: 6 additions & 4 deletions src/rt/stdenv.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,14 @@ static time_t to_time_t(const time_record_t *tr)
DLLEXPORT
void _std_env_stop(int32_t finish, int32_t have_status, int32_t status)
{
if (have_status)
if (have_status) {
notef("%s called with status %d", finish ? "FINISH" : "STOP", status);
else
jit_abort_with_status(status);
}
else {
notef("%s called", finish ? "FINISH" : "STOP");

jit_abort(status);
jit_abort();
}
}

DLLEXPORT
Expand Down
2 changes: 1 addition & 1 deletion src/rt/verilog.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ DLLEXPORT
void __nvc_sys_finish(void)
{
notef("$finish called");
jit_abort(0);
jit_abort();
}

DLLEXPORT
Expand Down
18 changes: 18 additions & 0 deletions test/regress/assert7.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
entity assert7 is
end entity;

use std.env.all;

architecture test of assert7 is
begin

p1: process is
begin
for i in 1 to 30 loop
assert false report "this is error " & integer'image(i);
end loop;
finish; -- Should preserve exit status
wait;
end process;

end architecture;
35 changes: 30 additions & 5 deletions test/regress/gold/assert7.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
(init): Assertion Error: Assertion violation.
assert7.vhd
|
8 | assert x > 0;
| ^^^^^ -1 > 0 is false
0ms+0: Assertion Error: this is error 1
0ms+0: Assertion Error: this is error 2
0ms+0: Assertion Error: this is error 3
0ms+0: Assertion Error: this is error 4
0ms+0: Assertion Error: this is error 5
0ms+0: Assertion Error: this is error 6
0ms+0: Assertion Error: this is error 7
0ms+0: Assertion Error: this is error 8
0ms+0: Assertion Error: this is error 9
0ms+0: Assertion Error: this is error 10
0ms+0: Assertion Error: this is error 11
0ms+0: Assertion Error: this is error 12
0ms+0: Assertion Error: this is error 13
0ms+0: Assertion Error: this is error 14
0ms+0: Assertion Error: this is error 15
0ms+0: Assertion Error: this is error 16
0ms+0: Assertion Error: this is error 17
0ms+0: Assertion Error: this is error 18
0ms+0: Assertion Error: this is error 19
0ms+0: Assertion Error: this is error 20
0ms+0: Assertion Error: this is error 21
0ms+0: Assertion Error: this is error 22
0ms+0: Assertion Error: this is error 23
0ms+0: Assertion Error: this is error 24
0ms+0: Assertion Error: this is error 25
0ms+0: Assertion Error: this is error 26
0ms+0: Assertion Error: this is error 27
0ms+0: Assertion Error: this is error 28
0ms+0: Assertion Error: this is error 29
0ms+0: Assertion Error: this is error 30
1 change: 1 addition & 0 deletions test/regress/testlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -793,3 +793,4 @@ view5 normal,2019
issue705 normal,2008
array17 normal,2008
stdenv5 normal,2019
assert7 fail,2008
1 change: 0 additions & 1 deletion test/unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ int main(int argc, char **argv)
mspace_stack_limit(MSPACE_CURRENT_FRAME);

opt_set_int(OPT_UNIT_TEST, 1);
opt_set_int(OPT_ERROR_LIMIT, -1);
opt_set_size(OPT_ARENA_SIZE, 1 << 20);
opt_set_str(OPT_GC_VERBOSE, getenv("NVC_GC_VERBOSE"));
opt_set_size(OPT_HEAP_SIZE, 128 * 1024);
Expand Down

0 comments on commit 63a8319

Please sign in to comment.