Skip to content

Commit

Permalink
Fix corner case identifying valid conversion functions
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Nov 5, 2015
1 parent bc6e483 commit c6dcd99
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/common.c
Expand Up @@ -772,4 +772,5 @@ void intern_strings(void)
wait_level_i = ident_new("wait_level");
impure_io_i = ident_new("impure_io");
simple_name_i = ident_new("simple_name");
conversion_i = ident_new("conversion");
}
1 change: 1 addition & 0 deletions src/common.h
Expand Up @@ -190,6 +190,7 @@ GLOBAL ident_t llvm_i;
GLOBAL ident_t wait_level_i;
GLOBAL ident_t impure_io_i;
GLOBAL ident_t simple_name_i;
GLOBAL ident_t conversion_i;

void intern_strings();

Expand Down
21 changes: 19 additions & 2 deletions src/parse.c
Expand Up @@ -903,8 +903,25 @@ static tree_t p_actual_part(void)
tree_set_loc(t, CURRENT_LOC);
return t;
}
else
return p_expression();

// If the actual part takes either the second or third form above then the
// argument to the function call is the actual designator but only if the
// call is to a named function rather than an operator
// This is import for identifying conversion functions later
const token_t next = peek();
const bool had_name = (next == tID || next == tSTRING);

tree_t designator = p_expression();

const bool could_be_conversion =
had_name
&& tree_kind(designator) == T_FCALL
&& tree_params(designator) == 1;

if (could_be_conversion)
tree_add_attr_int(designator, conversion_i, 1);

return designator;
}

static void p_association_element(tree_t map, add_func_t addf)
Expand Down
3 changes: 2 additions & 1 deletion src/sem.c
Expand Up @@ -5734,7 +5734,8 @@ static bool sem_check_actual(formal_map_t *formals, int nformals,
// Conversion functions are in LRM 93 section 4.3.2.2

tree_t func = tree_ref(value);
if ((tree_ports(func) == 1) && (tree_params(value) == 1))
if (tree_ports(func) == 1 && tree_params(value) == 1
&& tree_attr_int(value, conversion_i, 0))
actual = tree_value(tree_param(value, 0));
}
}
Expand Down
21 changes: 21 additions & 0 deletions test/sem/ports.vhd
Expand Up @@ -334,3 +334,24 @@ architecture other2 of top is

begin
end architecture;

-------------------------------------------------------------------------------

architecture actual_func of top is
component comp is
port (
i : in integer );
end component;
signal s : integer;
function "not"(x : integer) return integer;
begin

c1: component comp
port map (
i => "not"(s) ); -- OK

c2: component comp
port map (
i => not s ); -- Error, not treated as conversion func

end architecture;
3 changes: 2 additions & 1 deletion test/test_sem.c
Expand Up @@ -105,12 +105,13 @@ START_TEST(test_ports)
{ 311, "cannot assign to input port X" },
{ 312, "cannot read output port Y" },
{ 332, "cannot read parameter X with mode IN" },
{ 355, "actual must be globally static expression or locally static" },
{ -1, NULL }
};
expect_errors(expect);

parse_and_check(T_PACKAGE, T_ENTITY, T_ARCH, T_ENTITY, T_ARCH, T_ARCH,
T_ARCH, T_ENTITY, T_ARCH, T_ARCH);
T_ARCH, T_ENTITY, T_ARCH, T_ARCH, T_ARCH);

fail_unless(parse() == NULL);
fail_unless(parse_errors() == 0);
Expand Down

0 comments on commit c6dcd99

Please sign in to comment.