@@ -16,25 +16,36 @@ module CPP-TRANSLATION-EXPR-NEW
16
16
imports CPP-ABSTRACT-SYNTAX
17
17
imports CPP-BITSIZE-SYNTAX
18
18
imports CPP-BUILTIN-SYNTAX
19
+ imports CPP-DYNAMIC-SYNTAX
20
+ imports CPP-SYNTAX
19
21
imports CPP-TRANSLATION-DECL-CLASS-SYNTAX
22
+ imports CPP-TRANSLATION-DECL-CLASS-DESTRUCTOR-SYNTAX
20
23
imports CPP-TRANSLATION-DECL-INITIALIZER-SYNTAX
21
- imports CPP-DYNAMIC-SYNTAX
22
24
imports CPP-TRANSLATION-OVERLOADING-SYNTAX
23
- imports CPP-SYNTAX
24
25
imports CPP-TRANSLATION-NAME-SYNTAX
25
26
imports CPP-TYPE-MAP-SYNTAX
26
27
imports CPP-TYPING-SYNTAX
27
28
28
29
context NewExpr(_, _, (HOLE:Expr => reval(HOLE)), _, _) [result(PRVal)]
29
30
30
- rule (.K => lookupAllocationFunction(operatornew, T, IsGlobal)) ~> NewExpr(IsGlobal::Bool, T:CPPType, NoExpression(), _, _)
31
+ rule (.K => lookupAllocationFunction(operatornew, T, IsGlobal))
32
+ ~> NewExpr(IsGlobal::Bool, T:CPPType, NoExpression(), _, _)
31
33
requires notBool isCPPArrayType(T)
32
- rule (.K => lookupAllocationFunction(operatornew[], getMostDerivedArrayElement(T), IsGlobal)) ~> NewExpr(IsGlobal::Bool, T:CPPType, _:PRVal, _, _)
33
- rule (.K => lookupAllocationFunction(operatornew[], getMostDerivedArrayElement(T), IsGlobal)) ~> NewExpr(IsGlobal::Bool, T:CPPArrayType, _, _, _)
34
34
35
- rule lookupAllocationFunction(X::CId, T::CPPType, IsGlobal:Bool) => qualifiedNameLookup(X, GlobalNamespace(), defaultMask)
35
+ rule (.K => lookupAllocationFunction(operatornew[], getMostDerivedArrayElement(T), IsGlobal))
36
+ ~> NewExpr(IsGlobal::Bool, T:CPPType, _:PRVal, _, _)
37
+
38
+ rule (.K => lookupAllocationFunction(operatornew[], getMostDerivedArrayElement(T), IsGlobal))
39
+ ~> NewExpr(IsGlobal::Bool, T:CPPArrayType, _, _, _)
40
+
41
+ rule lookupAllocationFunction(X::CId, T::CPPType, IsGlobal:Bool)
42
+ => qualifiedNameLookup(X, GlobalNamespace(), defaultMask)
36
43
requires IsGlobal orBool notBool isCPPClassType(T)
37
- rule lookupAllocationFunction(X::CId, t(... st: classType(C::Class)), false) => qualifiedNameLookup(X, C, defaultMask) orIfNotFound qualifiedNameLookup(X, GlobalNamespace(), defaultMask)
44
+
45
+ rule lookupAllocationFunction(X::CId, t(... st: classType(C::Class)), false)
46
+ => qualifiedNameLookup(X, C, defaultMask)
47
+ orIfNotFound
48
+ qualifiedNameLookup(X, GlobalNamespace(), defaultMask)
38
49
39
50
rule (cSet(... id: Q::QualId) #as C:CandidateSet => resolveOverload(C, list(ListItem(pre(newSize(!I), noTrace, type(size_t)) * prv(byteSizeofType(T), noTrace, type(size_t))) P),
40
51
Name(NoNNS(), operatornew[]))
@@ -48,30 +59,101 @@ module CPP-TRANSLATION-EXPR-NEW
48
59
requires getId(Q) ==K operatornew
49
60
50
61
rule R:PRExpr ~> I:Int ~> NewExpr(_, T:CPPType, Size:PRExpr, Init::Init, _) #as E:Expr
51
- => computeNewInit(R, T, Size, E, I, figureInit(le(ExecName(NoNNS(), #NoName(I)), noTrace, t(noQuals, .Set, dynamicArrayType(T, newSize(I)))), t(noQuals, .Set, dynamicArrayType(T, newSize(I))), Init, DirectInit()))
62
+ => computeNewInit(
63
+ R, T, Size, E, I,
64
+ figureInit(
65
+ le(ExecName(NoNNS(), #NoName(I)), noTrace, t(noQuals, .Set, dynamicArrayType(T, newSize(I)))),
66
+ t(noQuals, .Set, dynamicArrayType(T, newSize(I))),
67
+ Init,
68
+ DirectInit()
69
+ )
70
+ )
71
+
52
72
rule R:PRExpr ~> I:Int ~> NewExpr(_, T:CPPType, prv(Size:Int, Tr::Trace, SizeT::CPPType), Init::Init, _) #as E:Expr
53
- => computeNewInit(R, T, prv(Size, Tr, SizeT), E, I, figureInit(le(ExecName(NoNNS(), #NoName(I)), noTrace, t(noQuals, .Set, arrayType(T, Size))), t(noQuals, .Set, arrayType(T, Size)), Init, DirectInit()))
73
+ => computeNewInit(
74
+ R, T, prv(Size, Tr, SizeT), E, I,
75
+ figureInit(
76
+ le(ExecName(NoNNS(), #NoName(I)), noTrace, t(noQuals, .Set, arrayType(T, Size))),
77
+ t(noQuals, .Set, arrayType(T, Size)),
78
+ Init,
79
+ DirectInit()
80
+ )
81
+ )
82
+
54
83
rule R:PRExpr ~> NewExpr(_, T:CPPType, NoExpression(), Init::Init, _) #as E:Expr
55
- => computeNewInit(R, T, NoExpression(), E, !I, figureInit(le(ExecName(NoNNS(), #NoName(!I:Int)), noTrace, T), T, Init, DirectInit()))
84
+ => computeNewInit(
85
+ R, T, NoExpression(), E, !I,
86
+ figureInit(
87
+ le(ExecName(NoNNS(), #NoName(!I:Int)), noTrace, T),
88
+ T,
89
+ Init,
90
+ DirectInit()
91
+ )
92
+ )
56
93
57
94
syntax Expr ::= computeNewInit(Expr, CPPType, AExpr, Expr, Int, K) [strict(6)]
58
95
59
- rule computeNewInit(R::Expr, T::CPPType, Size:Expr, E::Expr, I::Int, Init:KResult)
60
- => pre(NewOp(T, R, Init, Size, I), hasTrace(E), type(pointerType(T)))
61
- rule computeNewInit(R::Expr, T::CPPType, NoExpression(), E::Expr, I::Int, Init:KResult)
62
- => pre(NewOp(T, R, Init, .K, I), hasTrace(E), type(pointerType(T)))
96
+ syntax K ::= ExprOrNothing(K) [function]
97
+ rule ExprOrNothing(E:Expr) => E
98
+ rule ExprOrNothing(_) => .K [owise]
99
+
100
+ rule computeNewInit(R::Expr, T::CPPType, Size::AExpr, E::Expr, I::Int, Init:KResult)
101
+ => New.potentiallyInvokeDestructor(T)
102
+ ~> pre(NewOp(T, R, Init, ExprOrNothing(Size), I), hasTrace(E), type(pointerType(T)))
103
+
104
+
105
+ // TODO(jan.tusil) test this with multidimensional arrays
106
+ //
107
+ // N4296 5.3.4/19
108
+ // N4778 7.6.2.4/21
109
+ // <quote>
110
+ // If the new-expression creates an array of objects of class type,
111
+ // the destructor is potentially invoked.
112
+ // </quote>
113
+ // <group>
114
+
115
+ syntax KItem ::= "New.potentiallyInvokeDestructor" "(" CPPType ")"
116
+
117
+ rule New.potentiallyInvokeDestructor(T:CPPArrayType)
118
+ => #if isCPPClassType(innerType(T)) #then
119
+ Class.potentiallyInvokeDestructor(classFromType(innerType(T)))
120
+ #else
121
+ .K
122
+ #fi
123
+
124
+ rule New.potentiallyInvokeDestructor(T::CPPType) => .K
125
+ requires notBool isCPPArrayType(T)
126
+
127
+ // </group>
128
+
129
+ rule getSecondDeleteArg(M::TypeMap, V::PRVal)
130
+ => #getSecondDeleteArg(M, func(type(void), ptr(type(void))), func(type(void), ptr(type(void)), type(size_t)), V)
63
131
64
- rule getSecondDeleteArg(M::TypeMap, V::PRVal) => #getSecondDeleteArg(M, func(type(void), ptr(type(void))), func(type(void), ptr(type(void)), type(size_t)), V)
65
132
syntax List ::= #getSecondDeleteArg(TypeMap, CPPType, CPPType, PRVal) [function]
66
133
rule #getSecondDeleteArg((T1 |-> _) (T2 |-> _) M::TypeMap, T1::CPPType, T2::CPPType, V::PRVal) => ListItem(V)
67
134
rule #getSecondDeleteArg(...) => .List [owise]
68
135
69
136
context DeleteExpr(_, _, (HOLE:Expr => reval(HOLE))) [result(PRVal)]
70
- rule (.K => lookupAllocationFunction(operatordelete, innerType(type(V)), IsGlobal)) ~> DeleteExpr(IsGlobal::Bool, false, V:PRVal)
137
+
138
+ rule (.K => lookupAllocationFunction(operatordelete, innerType(type(V)), IsGlobal))
139
+ ~> DeleteExpr(IsGlobal::Bool, false, V:PRVal)
71
140
requires isCPPPointerType(type(V)) andBool #fun(InnerT::CPPType => notBool isCPPClassType(InnerT) orBool notBool hasDestructorThat({InnerT}:>CPPClassType, #klabel(`isVirtualDestructor`)))(innerType(type(V)))
72
- rule (cSet(Cands::TypeMap, Q::QualId) #as C:CandidateSet => resolveOverload(C, list(ListItem(le(ExecName(NoNNS(), #NoName(!I:Int)), noTrace, type(V))) getSecondDeleteArg(Cands, pre(newSize(!I), noTrace, type(size_t)))), Name(NoNNS(), operatordelete))
73
- ~> !I:Int)
141
+
142
+ rule (
143
+ cSet(Cands::TypeMap, Q::QualId) #as C:CandidateSet
144
+ => resolveOverload(
145
+ C,
146
+ list(
147
+ ListItem(le(ExecName(NoNNS(), #NoName(!I:Int)), noTrace, type(V)))
148
+ getSecondDeleteArg(Cands, pre(newSize(!I), noTrace, type(size_t)))
149
+ ),
150
+ Name(NoNNS(), operatordelete)
151
+ )
152
+ ~> !I:Int
153
+ )
74
154
~> DeleteExpr(_, false, V::PRVal)
75
- rule R:PRExpr ~> I:Int ~> DeleteExpr(IsGlobal::Bool, false, V:PRVal) => pre(DeleteOp(V, R, .K, I), hasTrace(DeleteExpr(IsGlobal, false, V)), type(void))
155
+
156
+ rule R:PRExpr ~> I:Int ~> DeleteExpr(IsGlobal::Bool, false, V:PRVal)
157
+ => pre(DeleteOp(V, R, .K, I), hasTrace(DeleteExpr(IsGlobal, false, V)), type(void))
76
158
77
159
endmodule
0 commit comments