From fca87fda9f011b69891cbf1663c1553b34546c8a Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 10 Nov 2022 21:46:01 +0000 Subject: [PATCH] Fix error with condition conversion ambiguity. Issue #568 --- src/names.c | 74 ++++++++++++++++++++++++++++++----------- test/parse/issue568.vhd | 15 +++++++++ test/test_parse.c | 27 +++++++++++++++ 3 files changed, 97 insertions(+), 19 deletions(-) create mode 100644 test/parse/issue568.vhd diff --git a/src/names.c b/src/names.c index 8bb318ee..c593eab6 100644 --- a/src/names.c +++ b/src/names.c @@ -2768,6 +2768,21 @@ static bool is_unambiguous(tree_t t) || (kind == T_REF && tree_has_ref(t)); } +static bool is_unambiguous_fcall(tree_t t) +{ + if (tree_kind(t) == T_FCALL) { + const int nparams = tree_params(t); + for (int i = 0; i < nparams; i++) { + if (!is_unambiguous(tree_value(tree_param(t, i)))) + return false; + } + + return true; + } + + return false; +} + static type_list_t possible_types(nametab_t *tab, tree_t value) { tree_kind_t kind = tree_kind(value); @@ -2849,31 +2864,52 @@ static void solve_subprogram_params(nametab_t *tab, tree_t call, overload_t *o) } } - // Make two additional passes: one to do function calls and a final - // catch-all + // Solve all parameters which are function calls with unambiguous + // arguments - for (int pass = 0; pass < 2; pass++) { - for (int i = 0; i < nparams; i++) { - if (pmask & (1 << i)) - continue; + for (int i = 0; i < nparams; i++) { + if (pmask & (1 << i)) + continue; - tree_t p = tree_param(call, i); - tree_t value = tree_value(p); - tree_kind_t kind = tree_kind(value); + tree_t p = tree_param(call, i); + tree_t value = tree_value(p); - if (o->error && o->initial == 0) { - // Avoid cascading errors from an undefined subprogram - tree_set_type(value, type_new(T_NONE)); - pmask |= 1 << i; - continue; - } + if (o->error && o->initial == 0) { + // Avoid cascading errors from an undefined subprogram + tree_set_type(value, type_new(T_NONE)); + pmask |= 1 << i; + } + else if (is_unambiguous_fcall(value)) { + solve_one_param(tab, p, o); + pmask |= (1 << i); + } + } - if (kind == T_FCALL || pass == 1) { - solve_one_param(tab, p, o); - pmask |= (1 << i); - } + // Solve all remaining function call parameters + + for (int i = 0; i < nparams; i++) { + if (pmask & (1 << i)) + continue; + + tree_t p = tree_param(call, i); + tree_t value = tree_value(p); + + if (tree_kind(value) == T_FCALL) { + solve_one_param(tab, p, o); + pmask |= (1 << i); } } + + // Catch-all pass for remaining parameters + + for (int i = 0; i < nparams; i++) { + if (pmask & (1 << i)) + continue; + + tree_t p = tree_param(call, i); + solve_one_param(tab, p, o); + pmask |= (1 << i); + } } static bool can_call_no_args(nametab_t *tab, tree_t decl) diff --git a/test/parse/issue568.vhd b/test/parse/issue568.vhd new file mode 100644 index 00000000..399d35c4 --- /dev/null +++ b/test/parse/issue568.vhd @@ -0,0 +1,15 @@ +package pack is + function "=" (L: bit; R: bit) return bit; +end package; + +use work.pack.all; + +entity issue568 is + generic (x : boolean); +end entity; + +architecture test of issue568 is + signal y : bit; +begin + p1: assert (y = '1') or (not x); +end architecture; diff --git a/test/test_parse.c b/test/test_parse.c index 8f0ad32b..20a923a4 100644 --- a/test/test_parse.c +++ b/test/test_parse.c @@ -4968,6 +4968,32 @@ START_TEST(test_issue539) } END_TEST +START_TEST(test_issue568) +{ + set_standard(STD_08); + + input_from_file(TESTDIR "/parse/issue568.vhd"); + + tree_t p = parse(); + fail_if(p == NULL); + fail_unless(tree_kind(p) == T_PACKAGE); + lib_put(lib_work(), p); + + tree_t e = parse(); + fail_if(e == NULL); + fail_unless(tree_kind(e) == T_ENTITY); + lib_put(lib_work(), e); + + tree_t a = parse(); + fail_if(a == NULL); + fail_unless(tree_kind(a) == T_ARCH); + + fail_unless(parse() == NULL); + + fail_if_errors(); +} +END_TEST + Suite *get_parse_tests(void) { Suite *s = suite_create("parse"); @@ -5064,6 +5090,7 @@ Suite *get_parse_tests(void) tcase_add_test(tc_core, test_typo); tcase_add_test(tc_core, test_issue532); tcase_add_test(tc_core, test_issue539); + tcase_add_test(tc_core, test_issue568); suite_add_tcase(s, tc_core); return s; -- 2.39.2