Skip to content

Commit 942f4f4

Browse files
committed
Nits in the typechecker and more tests
1 parent 7fc2910 commit 942f4f4

File tree

7 files changed

+209
-40
lines changed

7 files changed

+209
-40
lines changed

src/Act/Syntax.hs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,48 @@ itemType (Item t _ _) = actType t
324324
isMapping :: StorageLocation t -> Bool
325325
isMapping = not . null . ixsFromLocation
326326

327+
posnFromExp :: Exp a t -> Pn
328+
posnFromExp e = case e of
329+
And p _ _ -> p
330+
Or p _ _ -> p
331+
Impl p _ _ -> p
332+
Neg p _ -> p
333+
LT p _ _ -> p
334+
LEQ p _ _ -> p
335+
GEQ p _ _ -> p
336+
GT p _ _ -> p
337+
LitBool p _ -> p
338+
-- integers
339+
Add p _ _ -> p
340+
Sub p _ _ -> p
341+
Mul p _ _ -> p
342+
Div p _ _ -> p
343+
Mod p _ _ -> p
344+
Exp p _ _ -> p
345+
LitInt p _ -> p
346+
IntEnv p _ -> p
347+
-- bounds
348+
IntMin p _ -> p
349+
IntMax p _ -> p
350+
UIntMin p _ -> p
351+
UIntMax p _ -> p
352+
InRange p _ _ -> p
353+
354+
-- bytestrings
355+
Cat p _ _ -> p
356+
Slice p _ _ _ -> p
357+
ByStr p _ -> p
358+
ByLit p _ -> p
359+
ByEnv p _ -> p
360+
-- contracts
361+
Create p _ _ -> p
362+
363+
-- polymorphic
364+
Eq p _ _ _ -> p
365+
NEq p _ _ _ -> p
366+
ITE p _ _ _ -> p
367+
TEntry p _ _ -> p
368+
Var p _ _ _ _ -> p
327369
--------------------------------------
328370
-- * Extraction from untyped ASTs * --
329371
--------------------------------------

src/Act/Type.hs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ andExps (c:cs) = foldl (\cs' c' -> And nowhere c' cs') c cs
489489

490490
-- | Check the type of an expression and construct a typed expression
491491
checkExpr :: forall a t. Typeable t => Env -> SType a -> U.Expr -> Err (Exp a t)
492-
checkExpr env@Env{constructors} typ e = case (typ, e) of
492+
checkExpr env@Env{constructors, calldata} typ e = case (typ, e) of
493493
-- Boolean expressions
494494
(SBoolean, U.ENot p v1) -> Neg p <$> checkExpr env SBoolean v1
495495
(SBoolean, U.EAnd p v1 v2) -> And p <$> checkExpr env SBoolean v1 <*> checkExpr env SBoolean v2
@@ -516,8 +516,8 @@ checkExpr env@Env{constructors} typ e = case (typ, e) of
516516
(SInteger, U.ECreate p c args) -> case Map.lookup c constructors of
517517
Just ctrs ->
518518
let (typs, ptrs) = unzip ctrs in
519-
checkIxs env p args (fmap PrimitiveType typs) `bindValidation` (\args ->
520-
pure (Create p c args) <* traverse_ (\(e, t) -> checkContractType env e t) (zip args ptrs))
519+
checkIxs env p args (fmap PrimitiveType typs) `bindValidation` (\args' ->
520+
pure (Create p c args') <* traverse_ (\(e', t) -> checkContractType env e' t) (zip args' ptrs))
521521
Nothing -> throw (p, "Unknown constructor " <> show c)
522522

523523
-- Control
@@ -537,16 +537,16 @@ checkExpr env@Env{constructors} typ e = case (typ, e) of
537537
_ -> throw (p, "Unknown environment variable " <> show v1)
538538

539539
-- Variable references
540-
(_, U.EUTEntry entry) | isCalldataEntry env entry -> -- TODO more principled way of treating timings
540+
(_, U.EUTEntry entry) | isCalldataEntry entry -> -- TODO more principled way of treating timings
541541
case (eqT @t @Timed, eqT @t @Untimed) of
542542
(Just Refl, _) -> validateVar env entry `bindValidation` \(vt@(FromVType typ'), ref) ->
543543
Var (getPosEntry entry) Pre typ vt ref <$ checkEq (getPosEntry entry) typ typ'
544544
(_, Just Refl) -> validateVar env entry `bindValidation` \(vt@(FromVType typ'), ref) ->
545545
Var (getPosEntry entry) Neither typ vt ref <$ checkEq (getPosEntry entry) typ typ'
546546
(_,_) -> error "Internal error: Timing should be either Timed or Untimed"
547547
-- Var (getPosEntry entry) Neither typ vt ref <$ checkEq (getPosEntry entry) typ typ'
548-
(_, U.EPreEntry entry) | isCalldataEntry env entry -> error "Not supported"
549-
(_, U.EPostEntry entry) | isCalldataEntry env entry -> error "Not supported"
548+
(_, U.EPreEntry entry) | isCalldataEntry entry -> error "Not supported"
549+
(_, U.EPostEntry entry) | isCalldataEntry entry -> error "Not supported"
550550
-- Storage references
551551
(_, U.EUTEntry entry) -> validateEntry env entry `bindValidation` \(vt@(FromVType typ'), ref) ->
552552
checkTime (getPosEntry entry) <*> (TEntry (getPosEntry entry) Neither (Item typ vt ref) <$ checkEq (getPosEntry entry) typ typ')
@@ -576,11 +576,11 @@ checkExpr env@Env{constructors} typ e = case (typ, e) of
576576
Nothing -> throw (pn, (tail . show $ typeRep @t) <> " variable needed here.")
577577

578578
-- TODO FIX
579-
isCalldataEntry Env{calldata} (U.EVar _ name) = case Map.lookup name calldata of
579+
isCalldataEntry (U.EVar _ name) = case Map.lookup name calldata of
580580
Just _ -> True
581581
_ -> False
582-
isCalldataEntry env (U.EMapping _ entry _) = isCalldataEntry env entry
583-
isCalldataEntry env (U.EField _ entry _) = isCalldataEntry env entry
582+
isCalldataEntry (U.EMapping _ entry _) = isCalldataEntry entry
583+
isCalldataEntry (U.EField _ entry _) = isCalldataEntry entry
584584

585585

586586
-- | Find the contract id of an expression with contract type
@@ -601,9 +601,9 @@ checkContractType :: Env -> TypedExp t -> Maybe Id -> Err ()
601601
checkContractType _ _ Nothing = pure ()
602602
checkContractType env (TExp _ e) (Just c) =
603603
findContractType env e `bindValidation` \oc ->
604-
case oc of -- TODO fix position
605-
Just c' -> assert (nowhere, "Expression was expected to have contract type " <> c <> " but has contract type " <> c') (c == c')
606-
Nothing -> throw (nowhere, "Expression was expected to have contract type " <> c)
604+
case oc of
605+
Just c' -> assert (posnFromExp e, "Expression was expected to have contract type " <> c <> " but has contract type " <> c') (c == c')
606+
Nothing -> throw (posnFromExp e, "Expression was expected to have contract type " <> c)
607607

608608
checkEq :: forall a b. Pn -> SType a -> SType b -> Err ()
609609
checkEq p t1 t2 = maybe err (\Refl -> pure ()) $ testEquality t1 t2

tests/frontend/fail/cast.act

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
constructor of A
2+
interface constructor(uint w1)
3+
4+
iff
5+
CALLVALUE == 0
6+
7+
creates
8+
uint w := w1
9+
10+
constructor of B
11+
interface constructor(uint z1)
12+
13+
iff
14+
CALLVALUE == 0
15+
16+
creates
17+
uint z := z1
18+
19+
constructor of C
20+
interface constructor(address a1, address a2)
21+
22+
pointers
23+
a1 |-> A
24+
a2 |-> B
25+
26+
iff
27+
CALLVALUE == 0
28+
29+
creates
30+
A a := a1
31+
B b := a2
32+
33+
constructor of D
34+
interface constructor(address a1, address a2)
35+
36+
pointers
37+
a1 |-> A
38+
39+
iff
40+
CALLVALUE == 0
41+
42+
creates
43+
C c1 := create C(a1, a2)

tests/hevm/pass/cast-5/cast-5.act

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
constructor of C
1+
constructor of A
2+
interface constructor(uint w1)
3+
4+
iff
5+
CALLVALUE == 0
6+
7+
creates
8+
uint w := w1
9+
10+
constructor of B
211
interface constructor(uint z1)
312

413
iff
@@ -7,28 +16,28 @@ iff
716
creates
817
uint z := z1
918

10-
constructor of A
11-
interface constructor(uint x1)
19+
constructor of C
20+
interface constructor(address a1, address a2)
1221

22+
pointers
23+
a1 |-> A
24+
a2 |-> B
25+
1326
iff
1427
CALLVALUE == 0
1528

1629
creates
17-
uint x := x1
18-
C c := create C(42)
30+
A a := a1
31+
B b := a2
1932

20-
21-
constructor of B
22-
interface constructor(address x, address y)
33+
constructor of D
34+
interface constructor(address a1, address a2)
2335

2436
pointers
25-
x |-> A
26-
y |-> A
37+
a1 |-> A
2738

2839
iff
29-
CALLVALUE == 0
30-
x =/= y
40+
CALLVALUE == 0
3141

3242
creates
33-
A a1 := x
34-
C c := x.c
43+
C c1 := create C(a1, a2)

tests/hevm/pass/cast-5/cast-5.sol

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pragma solidity >=0.8.0;
22

3-
contract C {
3+
contract A {
44
uint z;
55

66
constructor(uint z1) {
@@ -9,25 +9,28 @@ contract C {
99

1010
}
1111

12+
contract B {
13+
uint t;
1214

13-
contract A {
14-
uint x;
15-
public C c;
16-
17-
constructor(uint x1) {
18-
x = x1;
19-
c = new C(42);
15+
constructor(uint t1) {
16+
t = t1;
2017
}
2118
}
2219

20+
contract C {
21+
A a;
22+
B b;
2323

24-
contract B {
25-
A a1;
26-
A a2;
24+
constructor(address x, address y) {
25+
a = A(x);
26+
b = B(y);
27+
}
28+
}
2729

30+
contract D {
31+
C c2;
32+
2833
constructor(address x, address y) {
29-
require (x != y);
30-
a1 = A(x);
31-
a2 = a1.c();
34+
c2 = new C(x,y);
3235
}
3336
}

tests/hevm/pass/cast-6/cast-6.act

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
constructor of C
2+
interface constructor(uint z1)
3+
4+
iff
5+
CALLVALUE == 0
6+
7+
creates
8+
uint z := z1
9+
10+
constructor of A
11+
interface constructor(uint x1)
12+
13+
iff
14+
CALLVALUE == 0
15+
16+
creates
17+
uint x := x1
18+
C c := create C(42)
19+
20+
21+
behaviour c of A
22+
interface c()
23+
24+
iff
25+
CALLVALUE == 0
26+
27+
returns (pre(c))
28+
29+
constructor of B
30+
interface constructor(address x)
31+
32+
pointers
33+
x |-> A
34+
35+
iff
36+
CALLVALUE == 0
37+
38+
creates
39+
A a := x
40+
C c := x.c

tests/hevm/pass/cast-6/cast-6.sol

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
pragma solidity >=0.8.0;
2+
3+
contract C {
4+
uint z;
5+
6+
constructor(uint z1) {
7+
z = z1;
8+
}
9+
10+
}
11+
12+
13+
contract A {
14+
uint x;
15+
C public c;
16+
17+
constructor(uint x1) {
18+
x = x1;
19+
c = new C(42);
20+
}
21+
}
22+
23+
24+
contract B {
25+
A a;
26+
C c;
27+
28+
constructor(address x) {
29+
a = A(x);
30+
c = a.c();
31+
}
32+
}

0 commit comments

Comments
 (0)