Function overloading not working as expected
sudden6 opened this issue · 2 comments
The following minimal code:
package repro is
subtype instruction32_t is bit_vector(31 downto 0);
subtype opcode32_t is bit_vector(6 downto 0);
function has_rd(op : opcode32_t) return boolean;
function has_rd(ins : instruction32_t) return boolean;
end;
package body repro is
function has_rd(op : opcode32_t) return boolean is
begin
return false;
end function;
function has_rd(ins : instruction32_t) return boolean is
begin
return true;
end function;
end package body;
Leads to this error, even though I believe it's correct VHDL-2008, because the functions differ in their subtypes:
nvc -a repro/overload.vhd
** Error: HAS_RD [INSTRUCTION32_T return BOOLEAN] already declared in this region
> repro/overload.vhd:6
|
5 | function has_rd(op : opcode32_t) return boolean;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ previous declaration was here
6 | function has_rd(ins : instruction32_t) return boolean;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate declaration
** Error: design unit depends on WORK.REPRO which was analysed with errors
> repro/overload.vhd:9
|
9 | package body repro is
| ^^^^^^^^^^^^^^^^^^
Version is current git:
nvc --version
nvc 1.12-devel (1.11.0.r182.gaea6ec4a) (Using LLVM 18.1.2)
Copyright (C) 2011-2024 Nick Gasson
This program comes with ABSOLUTELY NO WARRANTY. This is free software, and
you are welcome to redistribute it under certain conditions. See the GNU
General Public Licence for details.
Subtypes are not distinct for the purposes of overload resolution. See section 4.5.1 of the 2008 LRM:
Two formal parameter lists are said to have the same parameter type profile if and only if they have the same number of parameters, and if at each parameter position the corresponding parameters have the same base type.
The error above then follows from the visibility rules in section 12.3:
Each of two declarations is said to be a homograph of the other if and only if both declarations have the same designator, and they denote different named entities, and either overloading is allowed for at most one of the two, or overloading is allowed for both declarations and they have the same parameter and result type profile (see 4.5.1).
So the two functions above are homographs since they have the same designator (has_rd
), the parameter base types are the same (bit_vector
), and the return type is the same. Then:
Two declarations that occur immediately within the same declarative region, [..], shall not be homographs, unless exactly one of them is the implicit declaration of a predefined operation or is an implicit alias of such an implicit declaration.
The error message could probably be improved a bit though.
For your example to work you need to make instruction32_t
and opcode32_t
separate types rather than subtypes. Something like:
type instruction32_t is array (31 downto 0) of bit;
type opcode32_t is array (6 downto 0) of bit;
function has_rd(op : opcode32_t) return boolean;
function has_rd(ins : instruction32_t) return boolean;
FWIW ModelSim gives a very similar error:
** Error: test.vhd(6): (vcom-1295) Function "has_rd" has already been defined in this region.
** =====> Prior declaration of "has_rd" is at test.vhd(5).
** Note: test.vhd(7): VHDL Compiler exiting
It now reports this:
** Error: homograph of HAS_RD [INSTRUCTION32_T return BOOLEAN] already declared in this region
> test.vhd:6
|
5 | function has_rd(op : opcode32_t) return boolean;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ previous declaration was here
6 | function has_rd(ins : instruction32_t) return boolean;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate declaration
|
= Note: only the base type is considered when determining if two overloads have the same
parameter type profile