From d3da4d01b2324b1dfec9a4fefe0ae2760a95db37 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 14 Aug 2022 14:05:02 +0100 Subject: [PATCH] Improve folding of for-generate expressions. Issue #514 --- src/elab.c | 17 +++++++++++++++-- test/elab/issue514.vhd | 42 ++++++++++++++++++++++++++++++++++++++++++ test/test_elab.c | 20 ++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 test/elab/issue514.vhd diff --git a/src/elab.c b/src/elab.c index 5e567dcb..9037c75a 100644 --- a/src/elab.c +++ b/src/elab.c @@ -1395,8 +1395,21 @@ static void elab_generate_range(tree_t r, int64_t *low, int64_t *high, error_at(tree_loc(r), "generate range is not static"); *low = *high = 0; } - else - range_bounds(r, low, high); + else if (!folded_bounds(r, low, high)) { + tree_t left = eval_must_fold(ctx->eval, tree_left(r)); + tree_t right = eval_must_fold(ctx->eval, tree_right(r)); + + int64_t ileft, iright; + if (folded_int(left, &ileft) && folded_int(right, &iright)) { + const bool asc = (tree_subkind(r) == RANGE_TO); + *low = asc ? ileft : iright; + *high = asc ? iright : ileft; + } + else { + error_at(tree_loc(r), "generate range is not static"); + *low = *high = 0; + } + } } static void elab_for_generate(tree_t t, elab_ctx_t *ctx) diff --git a/test/elab/issue514.vhd b/test/elab/issue514.vhd new file mode 100644 index 00000000..3c95655e --- /dev/null +++ b/test/elab/issue514.vhd @@ -0,0 +1,42 @@ +package pack is + type params is record + x, y : integer; + end record; +end package; + +------------------------------------------------------------------------------- + +use work.pack.all; + +entity sub is + generic ( p : params ); +end entity; + +architecture test of sub is + constant px : integer := p.x; + constant py : integer := p.y; +begin + + g: for i in px to py generate + end generate; + +end architecture; + +------------------------------------------------------------------------------- + +use work.pack.all; + +entity issue514 is +end entity; + +architecture test of issue514 is + function get_params return params is + begin + return (x => 4, y => 6); + end function; +begin + + u: entity work.sub + generic map (p => get_params); + +end architecture; diff --git a/test/test_elab.c b/test/test_elab.c index 9e2fa133..9e7227d4 100644 --- a/test/test_elab.c +++ b/test/test_elab.c @@ -1177,6 +1177,25 @@ START_TEST(test_comp4) } END_TEST +START_TEST(test_issue514) +{ + input_from_file(TESTDIR "/elab/issue514.vhd"); + + tree_t e = run_elab(); + fail_if(e == NULL); + + tree_t b0 = tree_stmt(e, 0); + fail_unless(tree_ident(b0) == ident_new("ISSUE514")); + fail_unless(tree_stmts(b0) == 1); + + tree_t u = tree_stmt(b0, 0); + fail_unless(tree_ident(u) == ident_new("U")); + fail_unless(tree_stmts(u) == 3); + + fail_if_errors(); +} +END_TEST + Suite *get_elab_tests(void) { Suite *s = suite_create("elab"); @@ -1244,6 +1263,7 @@ Suite *get_elab_tests(void) tcase_add_test(tc, test_neorv1); tcase_add_test(tc, test_toplevel4); tcase_add_test(tc, test_comp4); + tcase_add_test(tc, test_issue514); suite_add_tcase(s, tc); return s; -- 2.39.2