From f5b67cd9821547e661c1505f4873b8a8a471081c Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 5 Dec 2024 11:28:39 +0000 Subject: [PATCH] Fix parser crash after invalid PSL directive. Fixes xxx --- src/lexer.l | 2 ++ src/parse.c | 59 +++++++++++++++++++++++++++++++++++++++++---- src/psl/psl-node.c | 5 +++- src/psl/psl-node.h | 1 + src/psl/psl-sem.c | 11 +++++++++ src/scan.c | 2 +- src/scan.h | 1 + test/psl/parse4.vhd | 3 +++ test/psl/sem1.vhd | 1 + test/test_psl.c | 2 ++ 10 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index fc6944a5b..b12f22ec0 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -279,6 +279,7 @@ NONDET ?i:nondet NONDET_V ?i:nondet_vector UNION ?i:union INF ?i:inf +ENDPOINT ?i:endpoint INTERCONNECT ?i:interconnect DELAYFILE ?i:delayfile @@ -610,6 +611,7 @@ BEFORE ?i:before "|->" { TOKEN(tSUFFIXOVR); } "|=>" { TOKEN(tSUFFIXNON); } {INF} { TOKEN(tINF); } +{ENDPOINT} { TOKEN(tENDPOINT); } "module" { return tMODULE; } "endmodule" { return tENDMODULE; } diff --git a/src/parse.c b/src/parse.c index 0fb70569b..7e1beafe8 100644 --- a/src/parse.c +++ b/src/parse.c @@ -9573,6 +9573,7 @@ static void p_block_declarative_item(tree_t parent) case tDEFAULT: case tSEQUENCE: case tPROPERTY: + case tENDPOINT: p_psl_declaration(parent); break; @@ -10997,7 +10998,7 @@ static void p_concurrent_statement_or_psl(tree_t parent) consume(tCOLON); tree_add_stmt(parent, p_psl_directive(label)); } - else if (scan(tDEFAULT, tSEQUENCE, tPROPERTY)) + else if (scan(tDEFAULT, tSEQUENCE, tPROPERTY, tENDPOINT)) p_psl_declaration(parent); else tree_add_stmt(parent, p_psl_directive(NULL)); @@ -12852,7 +12853,8 @@ static psl_node_t p_psl_verification_directive(void) case tCOVER: return p_psl_cover_directive(); default: - one_of(tASSERT, tASSUME, tCOVER); + one_of(tASSERT, tASSUME, tASSUMEG, tRESTRICT, tRESTRICTG, tFAIRNESS, + tSTRONG, tCOVER); return NULL; } } @@ -12873,11 +12875,14 @@ static tree_t p_psl_directive(ident_t label) insert_names_for_psl(nametab); psl_node_t p = p_psl_verification_directive(); - tree_set_psl(t, p); scan_as_vhdl(); - psl_check(p, nametab); + if (p != NULL) { + tree_set_psl(t, p); + psl_check(p, nametab); + } + pop_scope(nametab); tree_set_loc(t, CURRENT_LOC); @@ -12982,6 +12987,47 @@ static tree_t p_psl_sequence_declaration(void) return t; } +static tree_t p_psl_endpoint_declaration(void) +{ + // sequence PSL_Identifier is Sequence ; + + BEGIN("PSL endpoint declaration"); + + scan_as_psl(); + + psl_node_t decl = psl_new(P_ENDPOINT_DECL); + + consume(tENDPOINT); + + ident_t ident = p_identifier(); + psl_set_ident(decl, ident); + + tree_t t = tree_new(T_PSL); + tree_set_psl(t, decl); + tree_set_ident(t, ident); + insert_name(nametab, t, NULL); + + push_scope(nametab); + insert_names_for_psl(nametab); + + consume(tIS); + + psl_node_t prop = p_psl_sequence(); + psl_set_value(decl, prop); + + consume(tSEMI); + + psl_set_loc(decl, CURRENT_LOC); + psl_check(decl, nametab); + + pop_scope(nametab); + + scan_as_vhdl(); + + tree_set_loc(t, CURRENT_LOC); + return t; +} + static void p_psl_declaration(tree_t parent) { // Property_Declaration | Sequence_Declaration | Clock_Declaration @@ -12998,8 +13044,11 @@ static void p_psl_declaration(tree_t parent) case tDEFAULT: tree_add_decl(parent, p_psl_clock_declaration()); break; + case tENDPOINT: + tree_add_decl(parent, p_psl_endpoint_declaration()); + break; default: - one_of(tPROPERTY, tSEQUENCE, tDEFAULT); + one_of(tPROPERTY, tSEQUENCE, tDEFAULT, tENDPOINT); break; } } diff --git a/src/psl/psl-node.c b/src/psl/psl-node.c index 5d7197084..2735569da 100644 --- a/src/psl/psl-node.c +++ b/src/psl/psl-node.c @@ -118,6 +118,9 @@ static const imask_t has_map[P_LAST_PSL_KIND] = { // P_CLOCKED (I_FOREIGN | I_VALUE | I_REF), + + // P_ENDPOINT_DECL + (I_IDENT | I_VALUE), }; static const char *kind_text_map[P_LAST_PSL_KIND] = { @@ -127,7 +130,7 @@ static const char *kind_text_map[P_LAST_PSL_KIND] = { "P_SERE", "P_REPEAT", "P_PROPERTY_INST", "P_SEQUENCE_INST", "P_UNION", "P_BUILTIN_FUNC", "P_VALUE_SET", "P_PARAM_DECL", "P_UNTIL", "P_ABORT", "P_BEFORE", "P_SUFFIX_IMPL", "P_LOGICAL", "P_RANGE", "P_PROC_BLOCK", - "P_PARAM_SERE", "P_CLOCKED", + "P_PARAM_SERE", "P_CLOCKED", "P_ENDPOINT_DECL", }; static const change_allowed_t change_allowed[] = { diff --git a/src/psl/psl-node.h b/src/psl/psl-node.h index aec9b44a3..e79353d21 100644 --- a/src/psl/psl-node.h +++ b/src/psl/psl-node.h @@ -54,6 +54,7 @@ typedef enum { P_PROC_BLOCK, P_PARAM_SERE, P_CLOCKED, + P_ENDPOINT_DECL, P_LAST_PSL_KIND } psl_kind_t; diff --git a/src/psl/psl-sem.c b/src/psl/psl-sem.c index 9ab167a1e..b9295cb38 100644 --- a/src/psl/psl-sem.c +++ b/src/psl/psl-sem.c @@ -73,6 +73,14 @@ static void psl_check_sequence_decl(psl_node_t p, nametab_t *tab) psl_check(psl_value(p), tab); } +static void psl_check_endpoint_decl(psl_node_t p, nametab_t *tab) +{ + psl_check(psl_value(p), tab); + + error_at(psl_loc(p), "PSL endpoint declarations are not supported as they " + "were not part of IEEE Std 1850-2010 or later standards"); +} + static void psl_check_top_level(psl_node_t p, nametab_t *tab) { if (psl_kind(p) == P_CLOCKED) @@ -439,6 +447,9 @@ void psl_check(psl_node_t p, nametab_t *tab) case P_SEQUENCE_DECL: psl_check_sequence_decl(p, tab); break; + case P_ENDPOINT_DECL: + psl_check_endpoint_decl(p, tab); + break; case P_HDL_EXPR: psl_check_hdl_expr(p, tab); break; diff --git a/src/scan.c b/src/scan.c index 39c2b09fb..d90cb4171 100644 --- a/src/scan.c +++ b/src/scan.c @@ -248,7 +248,7 @@ const char *token_str(token_t tok) "shortint", "longint", "int", "integer", "time", "typedef", "logic", "enum", "tagged", "abort", "sync_abort", "async_abort", "before", "before!", "before_", "before!_", "|->", "|=>", "next", "inf", - "repeat", "do", + "repeat", "do", "endpoint", }; if (tok >= 200 && tok - 200 < ARRAY_LEN(token_strs)) diff --git a/src/scan.h b/src/scan.h index 093979589..d429758fd 100644 --- a/src/scan.h +++ b/src/scan.h @@ -406,5 +406,6 @@ bool is_scanned_as_psl(void); #define tINF 506 #define tREPEAT 507 #define tDO 508 +#define tENDPOINT 509 #endif // _SCAN_H diff --git a/test/psl/parse4.vhd b/test/psl/parse4.vhd index fcf41686a..312c470cb 100644 --- a/test/psl/parse4.vhd +++ b/test/psl/parse4.vhd @@ -55,4 +55,7 @@ begin -- Paramterized SERE -- psl cover {for i in {1 to 3}: && {seq_b(i)}}; + -- Garbage after PSL directive + -- psl asfasfa; + end architecture; diff --git a/test/psl/sem1.vhd b/test/psl/sem1.vhd index 48b5c045c..942f921ea 100644 --- a/test/psl/sem1.vhd +++ b/test/psl/sem1.vhd @@ -38,5 +38,6 @@ begin -- psl assert {x[*]}[->1]; -- Error -- psl assert {x[*1 to clk]}; -- Error -- psl assert {z [[foo <= 1;]]}; -- Error + -- psl endpoint e1 is {x; y}; -- Not supported end architecture; diff --git a/test/test_psl.c b/test/test_psl.c index 1be6b4fe7..20444a330 100644 --- a/test/test_psl.c +++ b/test/test_psl.c @@ -137,6 +137,7 @@ START_TEST(test_sem1) { 39, "expression must be a PSL Number but have type BIT" }, { 40, "no visible declaration for FOO" }, { 40, "no visible declaration for Z" }, + { 41, "PSL endpoint declarations are not supported" }, { -1, NULL } }; expect_errors(expect); @@ -184,6 +185,7 @@ START_TEST(test_parse4) const error_t expect[] = { { 53, "FOO is not a PSL sequence" }, + { 59, "unexpected ; while parsing architecture statement part" }, { -1, NULL } }; expect_errors(expect);