summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex AUVOLAT <alex.auvolat@ens.fr>2014-01-09 11:49:54 +0100
committerAlex AUVOLAT <alex.auvolat@ens.fr>2014-01-09 11:49:54 +0100
commitd0798a5e0d3828b491ed35b2f62edf6aef199e2b (patch)
tree56a17e80d66da133da675e6f6a2ad6d9138520d2
parent56fdab2ff0caaaa88a152ef06aef821f432fe488 (diff)
downloadLPC-Projet-d0798a5e0d3828b491ed35b2f62edf6aef199e2b.tar.gz
LPC-Projet-d0798a5e0d3828b491ed35b2f62edf6aef199e2b.zip
Reject redefinition of virtual methods with different return type.
-rw-r--r--src/typing.ml10
-rw-r--r--tests/typing/bad/testfile-invalid-virtual-redef.cpp11
-rw-r--r--tests/typing/good/testfile-return-type-redef.cpp11
3 files changed, 28 insertions, 4 deletions
diff --git a/src/typing.ml b/src/typing.ml
index bc53dff..2b0be10 100644
--- a/src/typing.ml
+++ b/src/typing.ml
@@ -677,10 +677,10 @@ let compute_tclass env c =
let ret_type = match proto.p_ret_type with
| Some k -> Some (build_type_or_ref k)
| None -> None in
+
(* If method is redefined from a virtual method of a parent class, it becomes virtual with same offset
Else if method is virtual, it gets new offset !
Else method is not virtual, everything is simple. *)
-
let rec check_in_super (s:tcls_hier) =
match List.fold_left (fun k s ->
let r = check_in_super s in
@@ -694,9 +694,11 @@ let compute_tclass env c =
| Some k -> Some k
| None ->
List.fold_left (fun f (i, p) ->
- if (p.tp_name = proto.p_name && (List.map fst p.tp_args) = args_types)
- then Some (s, i)
- else f) None s.h_vtable
+ if (p.tp_name = proto.p_name && (List.map fst p.tp_args) = args_types && p.tp_virtual <> None)
+ then begin
+ ty_assert (p.tp_ret_type = ret_type) "Virtual method must be redefined with same return type.";
+ Some (s, i)
+ end else f) None s.h_vtable
in let super = match check_in_super hier with
| None -> if virt then
(* allocate new spot in vtable of this object *)
diff --git a/tests/typing/bad/testfile-invalid-virtual-redef.cpp b/tests/typing/bad/testfile-invalid-virtual-redef.cpp
new file mode 100644
index 0000000..263ec62
--- /dev/null
+++ b/tests/typing/bad/testfile-invalid-virtual-redef.cpp
@@ -0,0 +1,11 @@
+class A {
+ public:
+ virtual int f(int x);
+};
+
+class B : public A {
+ public:
+ virtual void f(int x);
+};
+
+int main() {}
diff --git a/tests/typing/good/testfile-return-type-redef.cpp b/tests/typing/good/testfile-return-type-redef.cpp
new file mode 100644
index 0000000..ff14d00
--- /dev/null
+++ b/tests/typing/good/testfile-return-type-redef.cpp
@@ -0,0 +1,11 @@
+class A {
+ public:
+ int f(int x);
+};
+
+class B : public A {
+ public:
+ void f(int x);
+};
+
+int main() {}