From f0b946cd1fa3321d93c03471b5f78bbb0770a8ac Mon Sep 17 00:00:00 2001 From: NikLeberg Date: Thu, 28 Nov 2024 11:07:21 +0000 Subject: [PATCH] Fix crash on package definition in interface decl. --- NEWS.md | 1 + src/names.c | 3 ++- src/parse.c | 17 +++++++++-------- test/parse/pkgindecl.vhd | 9 +++++++++ test/test_parse.c | 23 +++++++++++++++++++++++ 5 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 test/parse/pkgindecl.vhd diff --git a/NEWS.md b/NEWS.md index cff605141..bd7a3454b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -34,6 +34,7 @@ format (#1071). - Added support for package external names (#1072). - Fixed parser hang for bit string literals (from @NikLeberg). +- Fixed a crash on an illegal package definition inside an interface. - Several other minor bugs were resolved (#1038, #1057, #1067). ## Version 1.14.2 - 2024-11-23 diff --git a/src/names.c b/src/names.c index 4d70f7e2b..9d7cf7483 100644 --- a/src/names.c +++ b/src/names.c @@ -2462,7 +2462,8 @@ void mangle_func(nametab_t *tab, tree_t decl) tree_t p = tree_port(decl, i); if (tree_class(p) == C_SIGNAL) tb_append(buf, 's'); - mangle_one_type(buf, tree_type(p)); + if (tree_has_type(p)) + mangle_one_type(buf, tree_type(p)); } if (nports > 0 || is_func) diff --git a/src/parse.c b/src/parse.c index cd3295c03..d79ddb873 100644 --- a/src/parse.c +++ b/src/parse.c @@ -5541,14 +5541,15 @@ static void p_formal_parameter_list(tree_t decl, type_t type) if (nports == 0) return; // Was parse error - tree_t p0 = tree_port(decl, 0); - type_add_param(type, tree_type(p0)); - - if (tree_has_value(p0)) - tree_set_flag(decl, TREE_F_CALL_NO_ARGS); - - for (int i = 1; i < nports; i++) - type_add_param(type, tree_type(tree_port(decl, i))); + for (int i = 0; i < nports; i++) { + tree_t p = tree_port(decl, i); + if (i == 0 && tree_has_value(p)) + tree_set_flag(decl, TREE_F_CALL_NO_ARGS); + if (tree_has_type(p)) + type_add_param(type, tree_type(p)); + else + type_add_param(type, type_new(T_NONE)); // Will raise error later + } } static tree_t p_interface_function_specification(void) diff --git a/test/parse/pkgindecl.vhd b/test/parse/pkgindecl.vhd new file mode 100644 index 000000000..a3ac7034a --- /dev/null +++ b/test/parse/pkgindecl.vhd @@ -0,0 +1,9 @@ +entity pkg_in_decl is begin end entity; + +architecture arch of pkg_in_decl is + function test( + package inner_pkg is end package; -- error + ) is begin + end function; +begin +end architecture; diff --git a/test/test_parse.c b/test/test_parse.c index ad3c2e4c6..7359cdc23 100644 --- a/test/test_parse.c +++ b/test/test_parse.c @@ -6991,6 +6991,28 @@ START_TEST(test_protected3) } END_TEST +START_TEST(test_pkgindecl) +{ + opt_set_int(OPT_RELAXED, 1); + set_standard(STD_08); + + input_from_file(TESTDIR "/parse/pkgindecl.vhd"); + + const error_t expect[] = { + { 5, "unexpected end while parsing interface package declaration, " + "expecting new"}, + { -1, NULL } + }; + expect_errors(expect); + + parse_and_check(T_ENTITY, T_ARCH); + + fail_unless(parse() == NULL); + + check_expected_errors(); +} +END_TEST + Suite *get_parse_tests(void) { Suite *s = suite_create("parse"); @@ -7159,6 +7181,7 @@ Suite *get_parse_tests(void) tcase_add_test(tc_core, test_issue1055); tcase_add_test(tc_core, test_hang); tcase_add_test(tc_core, test_protected3); + tcase_add_test(tc_core, test_pkgindecl); suite_add_tcase(s, tc_core); return s;