From ed4e5ca96afb94b43c3cdbd05112abaf1debe4b8 Mon Sep 17 00:00:00 2001 From: NikLeberg Date: Tue, 26 Nov 2024 10:13:44 +0000 Subject: [PATCH] Fix crash on invalid subtype indication. Issue #1038 --- src/names.c | 16 ++++++++++++---- src/sem.c | 6 +++++- test/parse/issue1038.vhd | 21 +++++++++++++++++---- test/test_parse.c | 7 ++++--- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/names.c b/src/names.c index 12cad6f58..4d70f7e2b 100644 --- a/src/names.c +++ b/src/names.c @@ -2104,7 +2104,8 @@ void resolve_resolution(nametab_t *tab, tree_t rname, type_t type) { // Finding the resolution function is a special case of overload resolution - if (tree_kind(rname) == T_ELEM_RESOLUTION) { + switch (tree_kind(rname)) { + case T_ELEM_RESOLUTION: if (type_is_record(type)) error_at(tree_loc(rname), "sorry, record element resolution is not " "supported yet"); @@ -2118,9 +2119,9 @@ void resolve_resolution(nametab_t *tab, tree_t rname, type_t type) tree_t a0 = tree_value(tree_assoc(rname, 0)); resolve_resolution(tab, a0, type_elem(type)); } - } - else { - assert(tree_kind(rname) == T_REF); + break; + + case T_REF: tree_set_ref(rname, NULL); type_set_push(tab); @@ -2137,6 +2138,13 @@ void resolve_resolution(nametab_t *tab, tree_t rname, type_t type) tree_set_ref(rname, finish_overload_resolution(&o)); type_set_pop(tab); + break; + + default: + error_at(tree_loc(rname), "not a valid resolution function for type %s", + type_pp(type)); + tree_set_type(rname, type_new(T_NONE)); + break; } } diff --git a/src/sem.c b/src/sem.c index 83d95fd18..f94309e7c 100644 --- a/src/sem.c +++ b/src/sem.c @@ -85,7 +85,11 @@ static bool sem_check_resolution(type_t type, tree_t res) } } - assert(tree_kind(res) == T_REF); + if (tree_kind(res) != T_REF) { + // Should have been caught during name resolution + assert(error_count() > 0); + return false; + } if (!tree_has_ref(res)) return false; diff --git a/test/parse/issue1038.vhd b/test/parse/issue1038.vhd index 7118dcefb..0f4b71bf3 100644 --- a/test/parse/issue1038.vhd +++ b/test/parse/issue1038.vhd @@ -10,10 +10,14 @@ package body foo_pkg is end package body bar_pkg; end package body foo_pkg; +-------------------------------------------------------------------------------- + package foo is alias TO_OCTAL_STRING is ns; end package foo; +-------------------------------------------------------------------------------- + ENTITY psl_func_in_primary IS END psl_func_in_primary; @@ -26,12 +30,21 @@ ARCHITECTURE arch OF psl_func_in_primary IS BEGIN END ARCHITECTURE arch; +-------------------------------------------------------------------------------- + package long_pkg is end package; package body long_pkg is - procedure bar is - begin - report "" ; natural ; - end procedure; + procedure bar is + begin + report "" ; natural ; + end procedure; end package body; + +-------------------------------------------------------------------------------- + +package resolution_fn_err is + constant c : positive; + subtype sub is c'active positive; +end package; diff --git a/test/test_parse.c b/test/test_parse.c index 5f94c006f..abc992041 100644 --- a/test/test_parse.c +++ b/test/test_parse.c @@ -6920,15 +6920,16 @@ START_TEST(test_issue1038) input_from_file(TESTDIR "/parse/issue1038.vhd"); const error_t expect[] = { - { 22, "unexpected next while parsing primary, expecting one of ??, (, " + { 26, "unexpected next while parsing primary, expecting one of ??, (, " "integer, real, null, identifier, string, bit string or new" }, - { 35, "no visible subprogram declaration for NATURAL" }, + { 41, "no visible subprogram declaration for NATURAL" }, + { 49, "not a valid resolution function for type POSITIVE" }, { -1, NULL } }; expect_errors(expect); parse_and_check(T_PACKAGE, T_PACK_BODY, T_PACKAGE, T_ENTITY, T_ARCH, - T_PACKAGE, T_PACK_BODY); + T_PACKAGE, T_PACK_BODY, T_PACKAGE); fail_unless(parse() == NULL);