aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl/vhdl-sem_expr.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-07-02 18:23:01 +0200
committerTristan Gingold <tgingold@free.fr>2020-07-02 18:23:05 +0200
commit0948af90416fe146923b8d1e89c7a86bb17efe66 (patch)
treefe7bbc302ceda63f79b6b663687cf550fb9fff26 /src/vhdl/vhdl-sem_expr.adb
parentc75cc353c3dd24097f29aaaacb96ae4a9598b642 (diff)
downloadghdl-0948af90416fe146923b8d1e89c7a86bb17efe66.tar.gz
ghdl-0948af90416fe146923b8d1e89c7a86bb17efe66.tar.bz2
ghdl-0948af90416fe146923b8d1e89c7a86bb17efe66.zip
vhdl-sem_expr: fix overload handling for conditional operation
Diffstat (limited to 'src/vhdl/vhdl-sem_expr.adb')
-rw-r--r--src/vhdl/vhdl-sem_expr.adb56
1 files changed, 44 insertions, 12 deletions
diff --git a/src/vhdl/vhdl-sem_expr.adb b/src/vhdl/vhdl-sem_expr.adb
index d38be0c7b..753a64429 100644
--- a/src/vhdl/vhdl-sem_expr.adb
+++ b/src/vhdl/vhdl-sem_expr.adb
@@ -2005,33 +2005,66 @@ package body Vhdl.Sem_Expr is
function Sem_Operator_Pass2_Interpretation
(Expr : Iir; Res_Type : Iir) return Iir
is
+ Is_Dyadic : constant Boolean :=
+ Get_Kind (Expr) in Iir_Kinds_Dyadic_Operator;
Decl : Iir;
Overload : Iir;
Overload_List : Iir_List;
Full_Compat : Iir;
+ Conv_Compat : Iir;
It : List_Iterator;
+ Level : Compatibility_Level;
begin
-- Second pass
-- Find the uniq implementation for this call.
Overload := Get_Implementation (Expr);
Overload_List := Get_Overload_List (Overload);
+
Full_Compat := Null_Iir;
+ Conv_Compat := Null_Iir;
+
It := List_Iterate (Overload_List);
while Is_Valid (It) loop
Decl := Get_Element (It);
- -- FIXME: wrong: compatibilty with return type and args.
- if Are_Types_Compatible (Get_Return_Type (Decl), Res_Type)
- /= Not_Compatible
- then
- if Full_Compat /= Null_Iir then
- Error_Operator_Overload (Expr, Overload_List);
- return Null_Iir;
- else
- Full_Compat := Decl;
- end if;
- end if;
+ Level := Sem_Operator_Compatibility (Decl, Expr, Is_Dyadic, Res_Type);
+ case Level is
+ when Not_Compatible =>
+ -- Ignored
+ null;
+ when Fully_Compatible =>
+ if Full_Compat = Null_Iir then
+ Full_Compat := Decl;
+ else
+ -- There are several fully compatible functions.
+ -- TODO: remove non-fully compatible functions from the list
+ -- before displaying the list.
+ Error_Operator_Overload (Expr, Overload_List);
+ return Null_Iir;
+ end if;
+ when Via_Conversion =>
+ if Conv_Compat = Null_Iir then
+ Conv_Compat := Decl;
+ else
+ -- Not yet an error, as there can be one fully compatible
+ -- function.
+ Conv_Compat := Overload;
+ end if;
+ end case;
Next (It);
end loop;
+
+ if Full_Compat = Null_Iir then
+ if Conv_Compat = Overload then
+ -- Several results through implicit conversion.
+ -- TODO: remove incompatible declarations from the list before
+ -- displaying it.
+ Error_Operator_Overload (Expr, Overload_List);
+ return Null_Iir;
+ else
+ Full_Compat := Conv_Compat;
+ end if;
+ end if;
+
Free_Iir (Overload);
Overload := Get_Type (Expr);
Free_Overload_List (Overload);
@@ -2041,7 +2074,6 @@ package body Vhdl.Sem_Expr is
"no matching function declarations for %n", +Expr);
return Null_Iir;
else
- Destroy_Iir_List (Overload_List);
return Full_Compat;
end if;
end Sem_Operator_Pass2_Interpretation;