Skip to content

Commit c7c1309

Browse files
committed
Extend typechecking for Econstructor/Eglobal
1 parent 4a8ce6c commit c7c1309

5 files changed

Lines changed: 173 additions & 10 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
Require Import skylabs.lang.cpp.syntax.typed.
2+
Require Import skylabs.lang.cpp.cpp.
3+
Require Import skylabs.lang.cpp.parser.plugin.cpp2v.
4+
5+
#[duplicates(error)]
6+
cpp.prog source flags "-std=c++20" prog cpp:{{
7+
struct C {
8+
int f;
9+
C(int);
10+
};
11+
12+
struct D {
13+
D();
14+
};
15+
16+
void not_ctor(C*, int) {}
17+
18+
int global_int;
19+
}}.
20+
21+
Definition C_name : name := Nglobal (Nid "C").
22+
Definition D_name : name := Nglobal (Nid "D").
23+
Definition C_ctor_int : name := Nscoped C_name (Nctor (Tint :: nil)).
24+
Definition not_ctor_name : name :=
25+
Nglobal (Nfunction function_qualifiers.N "not_ctor" (Tptr (Tnamed C_name) :: Tint :: nil)).
26+
Definition global_int_name : name := Nglobal (Nid "global_int").
27+
Definition C_field_f : name := Nscoped C_name (Nid "f").
28+
Definition C_field_missing : name := Nscoped C_name (Nid "missing").
29+
Definition missing_global : name := Nglobal (Nid "missing").
30+
31+
Goal exists ov, source.(symbols) !! C_ctor_int = Some ov.
32+
Proof. vm_compute. eauto. Qed.
33+
34+
Goal exists ov, source.(symbols) !! not_ctor_name = Some ov.
35+
Proof. vm_compute. eauto. Qed.
36+
37+
Goal trace.runO (typed.decltype.check_tu source) = Some tt.
38+
Proof. vm_compute. reflexivity. Qed.
39+
40+
Goal trace.runO (typed.decltype.of_expr source
41+
(Econstructor C_ctor_int (Eint 0 Tint :: nil) (Tnamed C_name))) =
42+
Some (Tnamed C_name).
43+
Proof. vm_compute. reflexivity. Qed.
44+
45+
Goal trace.runO (typed.decltype.of_expr source
46+
(Econstructor C_ctor_int (Eint 0 Tint :: nil)
47+
(Tarray (Tnamed C_name) 3))) =
48+
Some (Tarray (Tnamed C_name) 3).
49+
Proof. vm_compute. reflexivity. Qed.
50+
51+
Goal trace.runO (typed.decltype.of_expr source
52+
(Esizeof (inr (Eglobal C_field_f Tint)) Tsize_t)) =
53+
Some Tsize_t.
54+
Proof. vm_compute. reflexivity. Qed.
55+
56+
Goal trace.runO (typed.decltype.of_expr source (Eglobal missing_global Tint)) = None.
57+
Proof. vm_compute. reflexivity. Qed.
58+
59+
Goal trace.runO (typed.decltype.of_expr source (Eglobal global_int_name Tbool)) = None.
60+
Proof. vm_compute. reflexivity. Qed.
61+
62+
Goal trace.runO (typed.decltype.of_expr source (Eglobal C_field_missing Tint)) = None.
63+
Proof. vm_compute. reflexivity. Qed.
64+
65+
Goal trace.runO (typed.decltype.of_expr source (Eglobal C_field_f Tbool)) = None.
66+
Proof. vm_compute. reflexivity. Qed.
67+
68+
Goal trace.runO (typed.decltype.of_expr source
69+
(Econstructor (Nscoped C_name (Nctor nil)) nil (Tnamed C_name))) = None.
70+
Proof. vm_compute. reflexivity. Qed.
71+
72+
Goal trace.runO (typed.decltype.of_expr source
73+
(Econstructor not_ctor_name (Eint 0 Tint :: nil) (Tnamed C_name))) = None.
74+
Proof. vm_compute. reflexivity. Qed.
75+
76+
Goal trace.runO (typed.decltype.of_expr source
77+
(Econstructor C_ctor_int nil (Tnamed C_name))) = None.
78+
Proof. vm_compute. reflexivity. Qed.
79+
80+
Goal trace.runO (typed.decltype.of_expr source
81+
(Econstructor C_ctor_int (Enull :: nil) (Tnamed C_name))) = None.
82+
Proof. vm_compute. reflexivity. Qed.
83+
84+
Goal trace.runO (typed.decltype.of_expr source
85+
(Econstructor C_ctor_int (Eint 0 Tint :: nil) (Tnamed D_name))) = None.
86+
Proof. vm_compute. reflexivity. Qed.

rocq-skylabs-brick/theories/lang/cpp/syntax/mtraverse.v

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,16 @@ Module MTraverse.
467467
<*> mret d.(d_exception)
468468
<*> traverse (T:=eta option) (traverse (T:=eta OrDefault) traverseS) d.(d_body).
469469

470+
Definition traverseOV (o : ObjValue) : F ObjValue :=
471+
match o with
472+
| Ovar t init =>
473+
Ovar <$> traverseT t <*> global_init.traverse traverseE init
474+
| Ofunction f => Ofunction <$> traverseF f
475+
| Omethod m => Omethod <$> traverseM m
476+
| Oconstructor c => Oconstructor <$> traverseCtor c
477+
| Odestructor d => Odestructor <$> traverseDtor d
478+
end.
479+
470480
Definition traverseMember (m : Member) : F Member :=
471481
mkMember
472482
<$> atomic_name.traverse traverseT m.(mem_name)

rocq-skylabs-brick/theories/lang/cpp/syntax/mtyped.v

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ Definition tu_to_ext (tu : translation_unit) : typed.decltype.internal.ext_tu :=
3636
end
3737
| None => None
3838
end
39+
; typed.decltype.internal.ext_values nm :=
40+
match trace.runO $ untempN nm with
41+
| Some nm =>
42+
match tu.(symbols) !! nm return option MObjValue with
43+
| Some o => trace.runO $ totempOV o
44+
| None => None
45+
end
46+
| None => None
47+
end
3948
|}.
4049

4150
#[local] Open Scope monad_scope.

rocq-skylabs-brick/theories/lang/cpp/syntax/typed.v

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ Module decltype.
8383
Section with_lang.
8484
Record ext_tu : Set :=
8585
{ ext_symbols : name -> option decltype
86-
; ext_types : name -> option GlobDecl }.
86+
; ext_types : name -> option GlobDecl
87+
; ext_values : name -> option ObjValue }.
8788

8889
#[local] Definition M : Set -> Type :=
8990
readerT.M (ext_tu * decltype * option exprtype * list (localname * decltype)) (trace.M Error.t).
@@ -113,6 +114,20 @@ Module decltype.
113114
| None => throw ("failed to find global "%bs, n)
114115
end.
115116

117+
Definition value (n : name) : M ObjValue :=
118+
let* osym := readerT.asks (fun '(tu, _, _, _) => tu.(ext_values) n) in
119+
match osym with
120+
| Some ov => mret ov
121+
| None => throw ("failed to find global value "%bs, n)
122+
end.
123+
124+
Definition constructor_decl (n : name) : M Ctor :=
125+
let* ov := value n in
126+
match ov with
127+
| Oconstructor c => mret c
128+
| _ => throw ("global value is not a constructor "%bs, n, ov)
129+
end.
130+
116131
Definition type_of_constant (n : name) (id : ident) : M decltype :=
117132
let* osym := readerT.asks (fun '(tu, _, _, _) => tu.(ext_types) $ Nscoped n (Nid id)) in
118133
match osym with
@@ -529,6 +544,49 @@ Module decltype.
529544
| _ => throw "can not increment or decrement bool"%bs
530545
end.
531546

547+
Definition field_type (fld : field_name.t) (ms : list Member) : M type :=
548+
match List.find (fun m => bool_decide (m.(mem_name) = fld)) ms with
549+
| Some m => mret $ normalize_type m.(mem_type)
550+
| None => throw ("failed to find field "%bs, fld)
551+
end.
552+
553+
Definition type_of_global_or_field (n : name) : M decltype :=
554+
let* osym := readerT.asks (fun '(tu, _, _, _) => tu.(ext_symbols) n) in
555+
match osym with
556+
| Some sym => mret sym
557+
| None =>
558+
match n with
559+
| Nscoped cls fld =>
560+
let* gd := global cls in
561+
match gd with
562+
| Gstruct st => field_type fld st.(s_fields)
563+
| Gunion un => field_type fld un.(u_fields)
564+
| _ => throw ("global scope is not an aggregate "%bs, cls, gd)
565+
end
566+
| _ => throw ("failed to find global "%bs, n)
567+
end
568+
end.
569+
570+
Definition class_type (t : type) : M name :=
571+
match class_name t with
572+
| Some cls => mret cls
573+
| None => throw ("not a class type "%bs, t)
574+
end.
575+
576+
Definition constructed_class (t : type) : M name :=
577+
match class_name t with
578+
| Some cls => mret cls
579+
| None =>
580+
match array_type t with
581+
| Some ety => class_type ety
582+
| None => throw ("constructor result is not a class or class array "%bs, t)
583+
end
584+
end.
585+
586+
Definition check_constructor_result (c : Ctor) (t : type) : M unit :=
587+
let* cls := constructed_class t in
588+
require_eq cls c.(c_class).
589+
532590
Definition of_expr_body (e : Expr) : M decltype :=
533591
trace e $
534592
let* result :=
@@ -556,14 +614,9 @@ Module decltype.
556614
let* _ := require_eq (Tenum n) ct in
557615
mret $ Tenum n
558616
| Eglobal nm ty =>
559-
(* TODO NAMES TYPING:
560-
1. fields are not included, these are necessary for <<sizeof()>> (see cxx/bitvector)
561-
*)
562-
(*
563-
let* from_env := type_of_global nm in
564-
trace ("from_env = ", from_env))%bs $
617+
let* from_env := type_of_global_or_field nm in
618+
trace ("from_env = "%bs, from_env) $
565619
let* _ := require_eq from_env (normalize_type ty) in
566-
*)
567620
mret $ tref QM (normalize_type ty)
568621
| Eglobal_member nm ty =>
569622
match nm with
@@ -743,8 +796,10 @@ Module decltype.
743796
const Tsize_t <$> guard (t = Tsize_t)
744797
| Eoffsetof _ _ t => mret t
745798
| Econstructor f es t =>
746-
(* TODO: check the type of the constructor [f] *)
799+
let* ctor := constructor_decl f in
747800
let* tes := traverse (T:=eta list) of_expr es in
801+
let* _ := check_args ctor.(c_arity) (snd <$> ctor.(c_params)) tes in
802+
let* _ := check_constructor_result ctor t in
748803
mret t
749804
| Elambda n es =>
750805
let* tes := traverse (T:=eta list) of_expr es in
@@ -1093,7 +1148,8 @@ Module decltype.
10931148

10941149
Definition tu_to_ext (tu : translation_unit) : internal.ext_tu :=
10951150
{| internal.ext_symbols nm := fmap (M:=fun t => option t) type_of_value $ tu.(symbols) !! nm
1096-
; internal.ext_types nm := types tu !! nm |}.
1151+
; internal.ext_types nm := types tu !! nm
1152+
; internal.ext_values nm := symbols tu !! nm |}.
10971153

10981154
Definition of_expr (tu : translation_unit) (e : Expr) : trace.M Error.t decltype :=
10991155
readerT.run (internal.of_expr e) (tu_to_ext tu, Tvoid, None, []).

rocq-skylabs-brick/theories/lang/cpp/syntax/untemp.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,12 @@ Definition untempE := M2S MTraverse.traverseE.
7171
Definition untempTA := M2S MTraverse.traverseTA.
7272
Definition untempTP := temp_param.traverse untempT.
7373
Definition untempGD := MTraverse.traverseGD (M2S MTraverse.mk_core_traversal).
74+
Definition untempOV := MTraverse.traverseOV (M2S MTraverse.mk_core_traversal).
7475

7576
Definition totempN := S2M MTraverse.traverseN.
7677
Definition totempT := S2M MTraverse.traverseT.
7778
Definition totempE := S2M MTraverse.traverseE.
7879
Definition totempTA := S2M MTraverse.traverseTA.
7980
Definition totempTP := temp_param.traverse totempT.
8081
Definition totempGD := MTraverse.traverseGD (S2M MTraverse.mk_core_traversal).
82+
Definition totempOV := MTraverse.traverseOV (S2M MTraverse.mk_core_traversal).

0 commit comments

Comments
 (0)