forked from kframework/c-semantics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpromotion.k
101 lines (92 loc) · 4.68 KB
/
promotion.k
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
module C-PROMOTION
imports C-COMMON-PROMOTION-SYNTAX
imports C-CONVERSION-SYNTAX
imports C-DYNAMIC-SYNTAX
imports C-TYPING-SYNTAX
imports C-ABSTRACT-SYNTAX
imports COMPAT-SYNTAX
rule L:KLabel(
(V:RValue => cast(promote(type(V)), V))
)
requires isIntegerType(type(V))
andBool isArithUnaryOp(#klabel(L))
andBool notBool isPromoted(type(V))
rule L:KLabel(
(V:RValue => cast(promote(type(V)), V))
, _
)
requires isIntegerType(type(V))
andBool isArithBinOp(#klabel(L))
andBool notBool isPromoted(type(V))
rule L:KLabel(
_,
(V:RValue => cast(promote(type(V)), V))
)
requires isIntegerType(type(V))
andBool isArithBinOp(#klabel(L))
andBool notBool isPromoted(type(V))
// fixme these could be done more cleanly
/*@ \fromStandard{\source[n1570]{\para{6.3.1.8}{1}}}{
Many operators that expect operands of arithmetic type cause conversions
and yield result types in a similar way. The purpose is to determine a
common real type for the operands and result. For the specified operands,
each operand is converted, without change of type domain, to a type whose
corresponding real type is the common real type. Unless explicitly stated
otherwise, the common real type is also the corresponding real type of the
result, whose type domain is the type domain of the operands if they are
the same, and complex otherwise. This pattern is called the usual
arithmetic conversions:
}*/
rule Lbl:KLabel(L:RValue, R:RValue)
=> Lbl(cast(
usualArithmeticConversion(type(L), type(R)), L),
cast(usualArithmeticConversion(type(L), type(R)), R))
requires isArithBinConversionOp(#klabel(Lbl))
andBool isArithmeticType(type(L))
andBool isArithmeticType(type(R))
andBool (type(L) =/=Type type(R))
rule Lbl:KLabel(tv(_, (T:Type => stripConstants(T))), R:RValue)
requires isArithBinOp(#klabel(Lbl))
andBool fromConstantExpr(T)
andBool notBool fromConstantExpr(type(R))
andBool (#klabel(Lbl) =/=K #klabel(`_==_`))
andBool (#klabel(Lbl) =/=K #klabel(`_!=_`))
rule Lbl:KLabel(L:RValue, tv(_, (T:Type => stripConstants(T))))
requires isArithBinOp(#klabel(Lbl))
andBool fromConstantExpr(T)
andBool notBool fromConstantExpr(type(L))
andBool (#klabel(Lbl) =/=K #klabel(`_==_`))
andBool (#klabel(Lbl) =/=K #klabel(`_!=_`))
rule Lbl:KLabel(tv(V::CValue, (T:Type => stripConstants(T))), R:RValue)
requires ((#klabel(Lbl) =/=K #klabel(`_==_`)) orBool (#klabel(Lbl) =/=K #klabel(`_!=_`)))
andBool fromConstantExpr(T)
andBool notBool fromConstantExpr(type(R))
andBool notBool isNullPointerConstant(tv(V, T))
rule Lbl:KLabel(L:RValue, tv(V::CValue, (T:Type => stripConstants(T))))
requires ((#klabel(Lbl) =/=K #klabel(`_==_`)) orBool (#klabel(Lbl) =/=K #klabel(`_!=_`)))
andBool fromConstantExpr(T)
andBool notBool fromConstantExpr(type(L))
andBool notBool isNullPointerConstant(tv(V, T))
rule Lbl:KLabel(te(_, (T:Type => stripConstants(T))), R:RValue)
requires isArithBinOp(#klabel(Lbl))
andBool fromConstantExpr(T)
andBool notBool fromConstantExpr(type(R))
andBool (#klabel(Lbl) =/=K #klabel(`_==_`))
andBool (#klabel(Lbl) =/=K #klabel(`_!=_`))
rule Lbl:KLabel(L:RValue, te(_, (T:Type => stripConstants(T))))
requires isArithBinOp(#klabel(Lbl))
andBool fromConstantExpr(T)
andBool notBool fromConstantExpr(type(L))
andBool (#klabel(Lbl) =/=K #klabel(`_==_`))
andBool (#klabel(Lbl) =/=K #klabel(`_!=_`))
rule Lbl:KLabel(te(V:K, (T:Type => stripConstants(T))), R:RValue)
requires ((#klabel(Lbl) =/=K #klabel(`_==_`)) orBool (#klabel(Lbl) =/=K #klabel(`_!=_`)))
andBool fromConstantExpr(T)
andBool notBool fromConstantExpr(type(R))
andBool notBool isNullPointerConstant(te(V, T))
rule Lbl:KLabel(L:RValue, te(V:K, (T:Type => stripConstants(T))))
requires ((#klabel(Lbl) =/=K #klabel(`_==_`)) orBool (#klabel(Lbl) =/=K #klabel(`_!=_`)))
andBool fromConstantExpr(T)
andBool notBool fromConstantExpr(type(L))
andBool notBool isNullPointerConstant(te(V, T))
endmodule