Skip to content

Commit 07b6e4b

Browse files
authored
Merge branch 'master' into lef/fix-694-eurydice
2 parents 273cdec + aa23aa4 commit 07b6e4b

31 files changed

+1680
-0
lines changed

.github/workflows/ci.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,72 @@ jobs:
245245
export CC=${{matrix.cc}}
246246
make -kj$(nproc) -C krmllib/dist/generic -f Makefile.basic
247247
248+
build-and-test-pulse:
249+
runs-on: ubuntu-latest
250+
needs: build-deps
251+
steps:
252+
- name: Setup ocaml
253+
uses: ocaml/setup-ocaml@v3
254+
with:
255+
ocaml-compiler: 5.3.0
256+
257+
# Note, we prefer to restore the -fstar2 cache, but if it doesn't exist,
258+
# we restore the latest normal one.
259+
- name: Restore OPAM state
260+
uses: actions/cache/restore@v4
261+
with:
262+
fail-on-cache-miss: true
263+
path: _opam
264+
key: opam-${{ runner.os }}-${{ runner.arch }}-fstar2-${{ github.run_id }}
265+
restore-keys: |
266+
opam-${{ runner.os }}-${{ runner.arch }}-fstar2-
267+
opam-${{ runner.os }}-${{ runner.arch }}-
268+
269+
# Build F*, branch fstar2
270+
- run: opam update
271+
- run: opam pin -n fstar git+https://github.com/FStarLang/FStar#fstar2
272+
- run: opam install fstar
273+
274+
# Save OPAM state, note fstar2- in key.
275+
- name: Save OPAM state
276+
uses: actions/cache/save@v4
277+
with:
278+
path: _opam
279+
key: opam-${{ runner.os }}-${{ runner.arch }}-fstar2-${{ github.run_id }}
280+
281+
- name: Install Z3 with script
282+
run: |
283+
wget https://raw.githubusercontent.com/FStarLang/FStar/refs/heads/master/.scripts/get_fstar_z3.sh -O get_fstar_z3.sh
284+
chmod +x get_fstar_z3.sh
285+
./get_fstar_z3.sh /usr/local/bin
286+
# If these fail, stop right now.
287+
- run: which z3-4.8.5
288+
- run: which z3-4.13.3
289+
290+
- uses: actions/checkout@master
291+
with:
292+
path: karamel
293+
294+
- uses: actions/setup-node@v4
295+
with:
296+
node-version: 16
297+
298+
- run: echo "KRML_HOME=$(pwd)/karamel" >> $GITHUB_ENV
299+
300+
- name: Karamel CI (test-pulse)
301+
working-directory: karamel
302+
run: |
303+
eval $(opam env)
304+
export OCAMLRUNPARAM=b
305+
make -kj$(nproc) test-pulse
306+
248307
# A single no-op job to use for branch protection
249308
ciok:
250309
runs-on: ubuntu-latest
251310
if: ${{ cancelled() || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'failure') }}
252311
needs:
253312
- build-and-test
313+
- build-and-test-pulse
254314
- build-krmllib
255315
steps:
256316
# Note: this only runs when a dependency fails. If they all succeed,

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ clean:
5656
test: all
5757
$(MAKE) -C test
5858

59+
# This depends on minimal since fstar2 (with Pulse) is not expected
60+
# to be able to build krmllib.
61+
test-pulse: minimal
62+
$(MAKE) -C test/pulse
63+
5964
# Auto-detection
6065
pre:
6166
@eval "$(FSTAR_OCAMLENV)" && \

test/pulse/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_output

test/pulse/ANF.expected.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* krml header omitted for test repeatability */
2+
3+
4+
#include "ANF.h"
5+
6+
extern krml_checked_int_t Prims_op_Addition(krml_checked_int_t x, krml_checked_int_t y);
7+
8+
void ANF_test(void)
9+
{
10+
krml_checked_int_t r = (krml_checked_int_t)0;
11+
krml_checked_int_t __anf0 = r;
12+
r = Prims_op_Addition(__anf0, (krml_checked_int_t)1);
13+
krml_checked_int_t __anf01 = r;
14+
r = Prims_op_Addition(__anf01, (krml_checked_int_t)1);
15+
krml_checked_int_t __anf02 = r;
16+
r = Prims_op_Addition(__anf02, (krml_checked_int_t)1);
17+
krml_checked_int_t __anf03 = r;
18+
r = Prims_op_Addition(__anf03, (krml_checked_int_t)1);
19+
}
20+

test/pulse/ANF.fst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module ANF
2+
3+
#lang-pulse
4+
open Pulse
5+
6+
fn test ()
7+
{
8+
let mut r = 0;
9+
r := !r + 1;
10+
r := !r + 1;
11+
r := !r + 1;
12+
r := !r + 1;
13+
}

test/pulse/BangBang.expected.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* krml header omitted for test repeatability */
2+
3+
4+
#include "BangBang.h"
5+
6+
int32_t BangBang_modify_nested_ptr(int32_t **x)
7+
{
8+
int32_t *__anf2 = *x;
9+
int32_t *__anf01 = *x;
10+
int32_t __anf1 = *__anf01;
11+
*__anf2 = __anf1 + (int32_t)2;
12+
int32_t *__anf03 = *x;
13+
int32_t __anf11 = *__anf03;
14+
return __anf11 + (int32_t)1;
15+
}
16+
17+
void BangBang_decr_uint(void)
18+
{
19+
uint32_t x = 1U;
20+
uint32_t __anf0 = x;
21+
x = __anf0 - 1U;
22+
}
23+

test/pulse/BangBang.fst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module BangBang
2+
open Pulse
3+
#lang-pulse
4+
5+
fn modify_nested_ptr (x: ref (ref Int32.t)) (#y: erased (ref Int32.t)) (#z: erased Int32.t { Int32.v z < Int.max_int Int32.n - 3 })
6+
preserves x |-> y
7+
requires reveal y |-> z
8+
returns z': Int32.t
9+
ensures reveal y |-> Int32.add z 2l
10+
ensures rewrites_to z' (Int32.add z 3l)
11+
{
12+
(!x) := (!(!x)) `Int32.add` 2l;
13+
((!(!x)) `Int32.add` 1l)
14+
}
15+
16+
fn decr_uint () {
17+
let mut x: UInt32.t = 1ul;
18+
x := !x `UInt32.sub` 1ul;
19+
}

test/pulse/Break.expected.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/* krml header omitted for test repeatability */
2+
3+
4+
#include "Break.h"
5+
6+
void Break_simple_break(void)
7+
{
8+
bool k = true;
9+
bool _break = false;
10+
bool cond;
11+
if (_break)
12+
cond = false;
13+
else
14+
cond = k;
15+
while (cond)
16+
{
17+
_break = true;
18+
bool ite;
19+
if (_break)
20+
ite = false;
21+
else
22+
ite = k;
23+
cond = ite;
24+
}
25+
}
26+
27+
void Break_break_continue_and_return(uint8_t which)
28+
{
29+
bool _return = false;
30+
uint32_t i = 0U;
31+
bool _break = false;
32+
bool cond;
33+
if (_break)
34+
cond = false;
35+
else if (_return)
36+
cond = false;
37+
else
38+
{
39+
uint32_t __anf0 = i;
40+
cond = __anf0 < 1000U;
41+
}
42+
while (cond)
43+
{
44+
bool _continue = false;
45+
if ((uint32_t)which == 0U)
46+
_break = true;
47+
bool _break1 = _break;
48+
if (!_break1)
49+
{
50+
if ((uint32_t)which == 1U)
51+
_continue = true;
52+
bool _continue1 = _continue;
53+
if (!_continue1)
54+
{
55+
if ((uint32_t)which == 2U)
56+
_return = true;
57+
bool _return1 = _return;
58+
if (!_return1)
59+
{
60+
uint32_t __anf0 = i;
61+
i = __anf0 + 1U;
62+
}
63+
}
64+
}
65+
bool ite;
66+
if (_break)
67+
ite = false;
68+
else if (_return)
69+
ite = false;
70+
else
71+
{
72+
uint32_t __anf0 = i;
73+
ite = __anf0 < 1000U;
74+
}
75+
cond = ite;
76+
}
77+
}
78+
79+
size_t Break_find_zero_with_break(int32_t *a, size_t sz)
80+
{
81+
size_t i = (size_t)0U;
82+
bool _break = false;
83+
bool cond;
84+
if (_break)
85+
cond = false;
86+
else
87+
{
88+
size_t __anf0 = i;
89+
cond = __anf0 < sz;
90+
}
91+
while (cond)
92+
{
93+
size_t __anf01 = i;
94+
int32_t __anf1 = a[__anf01];
95+
if (__anf1 == (int32_t)0)
96+
_break = true;
97+
bool _break1 = _break;
98+
if (!_break1)
99+
{
100+
size_t __anf02 = i;
101+
i = __anf02 + (size_t)1U;
102+
}
103+
bool ite;
104+
if (_break)
105+
ite = false;
106+
else
107+
{
108+
size_t __anf0 = i;
109+
ite = __anf0 < sz;
110+
}
111+
cond = ite;
112+
}
113+
return i;
114+
}
115+

test/pulse/Break.fst

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module Break
2+
open Pulse
3+
open Pulse.Lib.WithPure
4+
#lang-pulse
5+
6+
fn simple_break ()
7+
{
8+
let mut k = true;
9+
while (!k)
10+
invariant live k
11+
ensures true
12+
{
13+
break;
14+
}
15+
}
16+
17+
fn break_continue_and_return (which: UInt8.t)
18+
{
19+
let mut i = 0ul;
20+
while (!i `UInt32.lt` 1000ul)
21+
invariant live i
22+
ensures true
23+
{
24+
if (which = 0uy) {
25+
break;
26+
};
27+
if (which = 1uy) {
28+
continue;
29+
};
30+
if (which = 2uy) {
31+
return;
32+
};
33+
i := !i `UInt32.add` 1ul;
34+
}
35+
}
36+
37+
fn find_zero_with_break (a: array Int32.t) (sz: SizeT.t)
38+
preserves pts_to a #'r 'va
39+
requires with_pure (SizeT.v sz <= Seq.length 'va)
40+
returns i: SizeT.t
41+
ensures pure (SizeT.v i <= SizeT.v sz /\
42+
(forall (j: nat). j < SizeT.v i ==> Seq.index 'va j <> 0l))
43+
ensures pure (SizeT.v i < SizeT.v sz ==> Seq.index 'va (SizeT.v i) == 0l)
44+
{
45+
let mut i: SizeT.t = 0sz;
46+
while (!i `SizeT.lt` sz)
47+
invariant live i
48+
invariant pure (SizeT.v !i <= SizeT.v sz /\
49+
(forall (j: nat). j < SizeT.v (!i) ==> Seq.index 'va j <> 0l))
50+
ensures (SizeT.v !i < SizeT.v sz /\ a.(!i) = 0l)
51+
{
52+
if (a.(!i) = 0l) {
53+
break;
54+
};
55+
56+
i := !i `SizeT.add` 1sz;
57+
};
58+
!i
59+
}

test/pulse/Bug356.expected.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* krml header omitted for test repeatability */
2+
3+
4+
#include "Bug356.h"
5+
6+
uint32_t Bug356_test(bool b)
7+
{
8+
if (b)
9+
return 1U;
10+
else
11+
{
12+
KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "");
13+
KRML_HOST_EXIT(255U);
14+
}
15+
}
16+
17+
uint32_t Bug356_test_final_admit(bool b)
18+
{
19+
if (b)
20+
return 1U;
21+
else
22+
{
23+
KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "");
24+
KRML_HOST_EXIT(255U);
25+
}
26+
}
27+
28+
void Bug356_test_unit_admit(bool x)
29+
{
30+
KRML_MAYBE_UNUSED_VAR(x);
31+
}
32+

0 commit comments

Comments
 (0)