Skip to content

Commit 6ea18d7

Browse files
authored
Destruct temporaries (2) (#572)
* createTemporary for bindParams * Delete local references when they go out of scope * destruct returned temporary * Forgotten test. * fix: forgotten `destructTemporaries` * Forgotten Makefile
1 parent 1df9636 commit 6ea18d7

File tree

15 files changed

+127
-34
lines changed

15 files changed

+127
-34
lines changed

semantics/common/execution/thread_local.k

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ module COMMON-THREAD-LOCAL
5353
<most-derived-class> .K </most-derived-class>
5454

5555
<constructed-temporaries> .List </constructed-temporaries>
56+
<ret-constructed-temporary> .K </ret-constructed-temporary>
5657

5758
// stack of block-control cells
5859
<block-stack color="violet"> .List </block-stack>

semantics/cpp/language/common/syntax.k

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ module CPP-SYNTAX
209209
| ExpressionStmt(Expr) [strict(c)]
210210
| PRValExpressionStmt(Expr) [strict(c)]
211211
| BreakStmt()
212-
| ReturnOp(Expr)
212+
| ReturnOp(init: Expr, obj: K)
213213
| IfStmt(Decl, Stmt, Stmt)
214214
| IfStmt(Expr, K, K)
215215
| WhileStmt(Decl, Stmt)

semantics/cpp/language/execution/decl/declarator.k

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,30 @@ module CPP-EXECUTION-DECL-DECLARATOR
1919
allocObject(bnew(!I:Int, T, Mods, D), T, byteSizeofType(T))
2020
#else .K #fi
2121
~> addToExecEnv(X, T, bnew(!I:Int, T, Mods, D), false)
22-
~> #if notBool isCPPRefType(T) #then
23-
LCregisterForDestruction(ExecName(NoNNS(), X))
24-
#else .K #fi
22+
~> LCregisterForDestruction(ExecName(NoNNS(), X))
2523
~> initializeObjectExec(Init)
26-
~> #if notBool isCPPRefType(T) #then
27-
LCupdateRegisteredForDestruction(size(LC))
28-
#else .K #fi
24+
~> LCupdateRegisteredForDestruction(size(LC))
2925
...</k>
3026
<duration> D::Duration </duration>
3127
<local-vars> Vars:Set (.Set => SetItem(X)) </local-vars>
3228
<locally-constructed> LC::List </locally-constructed>
3329
requires notBool X in Vars andBool X =/=K #NoName
3430

35-
syntax KItem ::= LCregisterForDestruction(Expr) [strict(1)]
31+
syntax KItem ::= LCregisterForDestruction(Expr)
32+
33+
// This works even if the declared variable is a reference.
34+
// The rule for reference rewriting (from dynamic.k)
35+
// can not apply, because the reference was not
36+
// initialized yet.
37+
context LCregisterForDestruction(HOLE:Expr) [result(LV)]
3638

3739
// we register the object for destruction before
3840
// its initializer runs (but with the `initialized` flag cleared)
3941
// so that if an exception is thrown in the initializer,
4042
// the allocated object gets deleted.
4143
// The `initialized` flag is set later
4244
// in `LCupdateRegisteredForDestruction()`.
43-
rule <k> LCregisterForDestruction(Obj:LVal) => .K ...</k>
45+
rule <k> LCregisterForDestruction(Obj:LV) => .K ...</k>
4446
<locally-constructed> .List =>
4547
ListItem(lcentry(Obj, false, true, false))
4648
...</locally-constructed>

semantics/cpp/language/execution/expr/reference.k

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1+
module CPP-EXECUTION-EXPR-REFERENCE-SYNTAX
2+
imports SYMLOC-SORTS
3+
4+
syntax KItem ::= deleteReference(SymLoc)
5+
6+
endmodule
7+
18
module CPP-EXECUTION-EXPR-REFERENCE
9+
imports CPP-EXECUTION-EXPR-REFERENCE-SYNTAX
210
imports C-CONFIGURATION
311
imports BOOL
412
imports CPP-BITSIZE-SYNTAX
@@ -41,4 +49,7 @@ module CPP-EXECUTION-EXPR-REFERENCE
4149

4250
rule referenceTarget(... loc: Loc::SymLoc) => Loc [owise]
4351

52+
rule <k> deleteReference(Loc::SymLoc) => .K ...</k>
53+
<references> R::Map => R[stripProv(Loc) <- undef] </references>
54+
4455
endmodule

semantics/cpp/language/execution/stmt/block.k

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module CPP-EXECUTION-STMT-BLOCK
2222
imports CPP-BUILTIN-SYNTAX
2323
imports CPP-DYNAMIC-SYNTAX
2424
imports CPP-EXECUTION-ENV-SYNTAX
25+
imports CPP-EXECUTION-EXPR-REFERENCE-SYNTAX
2526
imports CPP-EXECUTION-FULL-EXPRESSION-SYNTAX
2627
imports CPP-EXECUTION-STMT-BLOCK-SYNTAX
2728
imports CPP-SYMLOC-SYNTAX
@@ -106,7 +107,7 @@ module CPP-EXECUTION-STMT-BLOCK
106107

107108
rule destructLocal(IsException:Bool,
108109
lcentry(
109-
lv(Loc::SymLoc, _, _) #as V::LVal,
110+
lv(Loc::SymLoc, _, T::CPPType) #as V::LVal,
110111
Initialized:Bool,
111112
CanBeVirtual::Bool,
112113
IsConstructor:Bool
@@ -119,11 +120,15 @@ module CPP-EXECUTION-STMT-BLOCK
119120
destruct(V, CanBeVirtual) ~> fullExpression
120121
#fi
121122
~>
122-
#if IsConstructor #then
123+
#if IsConstructor orBool isCPPRefType(T) #then
123124
.K
124125
#else
125126
deleteObject(base(Loc))
126127
#fi
128+
~>
129+
#if isCPPRefType(T) #then
130+
deleteReference(Loc)
131+
#else .K #fi
127132

128133
syntax KItem ::= "unfoldBlockStack"
129134

semantics/cpp/language/execution/stmt/return.k

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,30 @@ module CPP-EXECUTION-STMT-RETURN
1515
imports CPP-DYNAMIC-SYNTAX
1616
imports CPP-EXECUTION-ENV-SYNTAX
1717
imports CPP-EXECUTION-FULL-EXPRESSION-SYNTAX
18+
imports CPP-EXECUTION-STMT-BLOCK-SYNTAX
1819
imports CPP-MEMORY-ALLOC-SYNTAX
1920
imports CPP-REFERENCE-SYNTAX
2021
imports CPP-SYNTAX
2122
imports CPP-TYPING-SYNTAX
2223

2324
// Return (from C++ function)
24-
rule <k> ReturnOp(V::Expr) => prepareReturn(getReturnType(T), V) ...</k>
25+
rule <k> ReturnOp(V::Expr, Obj::Expr) => prepareReturn(getReturnType(T), V, Obj) ...</k>
2526
<curr-scope> blockScope(_, Base::SymBase, _) </curr-scope>
2627
<functions>... Base |-> functionObject(_, T::CPPType, _, _) ...</functions>
2728

28-
syntax KItem ::= prepareReturn(CPPType, K)
29+
syntax KItem ::= prepareReturn(CPPType, K, KItem)
2930

30-
rule prepareReturn(T::CPPType, Init:KItem)
31+
context prepareReturn(_, _, HOLE:Expr) [result(LV)]
32+
33+
rule <k> prepareReturn(T::CPPType, Init:KItem, Obj:LV)
3134
=> Return'(Init, T)
35+
...</k>
36+
<ret-constructed-temporary>
37+
.K => lcentry(Obj, false, true, false)
38+
</ret-constructed-temporary>
3239
requires notBool isCPPVoidType(T)
3340

34-
rule prepareReturn(t(... st: void) #as T::CPPType, V:PRVal) => Return''(V)
41+
rule prepareReturn(t(... st: void) #as T::CPPType, V:PRVal, _) => Return''(V)
3542

3643
syntax KItem ::= "Return'" "(" KItem "," CPPType ")" [strict(c; 1)]
3744

@@ -66,13 +73,15 @@ module CPP-EXECUTION-STMT-RETURN
6673
// Return (to C++ function)
6774
rule <k> return(V:Val) ~> _
6875
=> exitRestrictBlock(.Set)
76+
~> addToCT(LCE)
6977
~> sequencePoint
7078
~> V
7179
~> K
7280
</k>
7381
(<function-control>
7482
<live-va-lists> .Set </live-va-lists>
7583
<block-stack> .List </block-stack>
84+
<ret-constructed-temporary> LCE::KItem </ret-constructed-temporary>
7685
...</function-control> => C)
7786
<call-stack>
7887
ListItem(
@@ -86,4 +95,14 @@ module CPP-EXECUTION-STMT-RETURN
8695
) => .List
8796
...</call-stack>
8897

98+
syntax KItem ::= addToCT(K)
99+
100+
rule addToCT(.K) => .K
101+
102+
rule <k> addToCT(lcentry(Obj::LV, _, _, _)) => .K ...</k>
103+
<constructed-temporaries> .List =>
104+
ListItem(lcentry(Obj, true, true, false))
105+
...</constructed-temporaries>
106+
107+
89108
endmodule

semantics/cpp/language/execution/stmt/try.k

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module CPP-EXECUTION-STMT-TRY
77
imports CPP-CONVERSION-SYNTAX
88
imports CPP-DYNAMIC-SYNTAX
99
imports CPP-EXECUTION-ENV-SYNTAX
10+
imports CPP-EXECUTION-STMT-BLOCK-SYNTAX
1011
imports CPP-EXECUTION-TEMPORARY-SYNTAX
1112
imports CPP-ERROR-SYNTAX
1213
imports CPP-SETTINGS-SYNTAX
@@ -25,14 +26,21 @@ module CPP-EXECUTION-STMT-TRY
2526
rule <k> ThrowOp(V:LVal) => throw(V) ...</k>
2627
<uncaught-exception> _ => true </uncaught-exception>
2728

29+
rule <k> (.K => destructLocal(true, LCE)) ~> throw(V::LVal) ...</k>
30+
<catch-handlers> .List </catch-handlers>
31+
<ret-constructed-temporary> lcentry(...) #as LCE::KItem => .K </ret-constructed-temporary>
32+
requires canUnwindStack(V)
33+
2834
rule <k> (.K => destructTemporaries(true)) ~> throw(V::LVal) ...</k>
2935
<catch-handlers> .List </catch-handlers>
36+
<ret-constructed-temporary> .K </ret-constructed-temporary>
3037
<constructed-temporaries> ListItem(_) _ </constructed-temporaries>
3138
requires canUnwindStack(V)
3239

3340
// if there are still blocks in this function, pop them
3441
rule <k> (.K => popBlock(true)) ~> throw(V::LVal) ...</k>
3542
<catch-handlers> .List </catch-handlers>
43+
<ret-constructed-temporary> .K </ret-constructed-temporary>
3644
<constructed-temporaries> .List </constructed-temporaries>
3745
<block-stack> ListItem(_) _ </block-stack>
3846
<block-history> ListItem(Num::Int) ...</block-history>
@@ -43,6 +51,7 @@ module CPP-EXECUTION-STMT-TRY
4351
// if we are at the root of a loop, pop it before popping further blocks
4452
rule <k> throw(V::LVal) ~> (_ => K) </k>
4553
<catch-handlers> .List </catch-handlers>
54+
<ret-constructed-temporary> .K </ret-constructed-temporary>
4655
<constructed-temporaries> .List </constructed-temporaries>
4756
<block-stack> ListItem(_) _ </block-stack>
4857
<block-history> ListItem(Num::Int) ...</block-history>
@@ -52,6 +61,7 @@ module CPP-EXECUTION-STMT-TRY
5261
// if there are still functions in the stack trace, pop them
5362
rule <k> (.K => unwindFunction) ~> throw(V::LVal) ...</k>
5463
<catch-handlers> .List </catch-handlers>
64+
<ret-constructed-temporary> .K </ret-constructed-temporary>
5565
<constructed-temporaries> .List </constructed-temporaries>
5666
<block-stack> .List </block-stack>
5767
<call-stack> ListItem(_) _ </call-stack>
@@ -161,7 +171,8 @@ module CPP-EXECUTION-STMT-TRY
161171

162172
rule <k> catchWithHandler(CatchOp(_, pushBlock(N::Int) ~> declareNonStaticObjectExec(... id: X::CId) #as D:KItem ~> Rest:K), V::LVal)
163173
~> tryMark(I::Int)
164-
=> popBlock(true)
174+
=> destructTemporaries(true)
175+
~> popBlock(true)
165176
~> pushBlock(N)
166177
~> setCurrentException(V)
167178
~> #if X ==K #NoName #then .K #else D #fi

semantics/cpp/language/execution/temporary.k

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module CPP-EXECUTION-TEMPORARY
99
imports C-CONFIGURATION
1010
imports CPP-DYNAMIC-SYNTAX
1111
imports CPP-EXECUTION-STMT-BLOCK-SYNTAX
12+
imports CPP-REFERENCE-SYNTAX
1213
imports COMPAT-SYNTAX
1314

1415
// This code works similarly to the code
@@ -21,23 +22,28 @@ module CPP-EXECUTION-TEMPORARY
2122
...</k>
2223
<constructed-temporaries> CT::List </constructed-temporaries>
2324

24-
syntax KItem ::= CTregisterForDestruction(Expr) [strict(1)]
25+
syntax KItem ::= CTregisterForDestruction(Expr)
2526

26-
rule <k> CTregisterForDestruction(Obj:LVal) => .K ...</k>
27+
// see LCregisterForDestruction in declarator.k
28+
context CTregisterForDestruction(HOLE:Expr) [result(LV)]
29+
30+
rule <k> CTregisterForDestruction(Obj:LV) => .K ...</k>
2731
<constructed-temporaries> .List =>
2832
ListItem(lcentry(Obj, false, true, false))
2933
...</constructed-temporaries>
3034

3135
syntax KItem ::= CTupdateRegisteredForDestruction(Int)
3236
| CTupdateRegisteredForDestruction2(idx: Int, entry: KItem)
3337

38+
syntax LVorRBR ::= LV | ReferenceBindingResult
39+
3440
// `-1 -Int Size` from the end is the index of the newly-added entry
35-
rule <k> V:LVal ~> CTupdateRegisteredForDestruction(Size::Int)
41+
rule <k> V:LVorRBR ~> CTupdateRegisteredForDestruction(Size::Int)
3642
=> CTupdateRegisteredForDestruction2(-1 -Int Size, CT[-1 -Int Size])
3743
~> V
3844
...</k>
3945
<constructed-temporaries> CT::List </constructed-temporaries>
40-
requires isEvalVal(V)
46+
requires isEvalVal(V) orBool isReferenceBindingResult(V)
4147

4248
rule <k> CTupdateRegisteredForDestruction2(Idx::Int,
4349
lcentry(Obj::LVal, false, CanBeVirtual::Bool, IsConstructor::Bool)) => .K

semantics/cpp/language/translation/decl/declarator.k

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,14 @@ module CPP-TRANSLATION-DECL-DECLARATOR
692692
syntax Stmt ::= getFunDefBody(TemplateInfo, QualId, CPPType, Stmt) [function]
693693

694694
rule getFunDefBody(noTemplate, QX::QualId, T::CPPType, Body::Stmt)
695-
=> TLabelStmt(funLabel(getId(QX)), #if isDestructorId(getId(QX)) #then ListItem(Destructor()) #else .List #fi ListItem(Body) ListItem(TReturnOp(getDefaultReturnOp(QX, getReturnType(T)))))
695+
=>
696+
TLabelStmt(funLabel(getId(QX)),
697+
#if isDestructorId(getId(QX)) #then ListItem(Destructor()) #else .List #fi
698+
ListItem(Body)
699+
ListItem(TReturnOp(
700+
getDefaultReturnOp(!I:Int, QX, getReturnType(T)),
701+
temp(!I:Int, type(int))))
702+
)
696703

697704
rule getFunDefBody(_, _, _, Body::Stmt) => Body [owise]
698705

@@ -707,12 +714,12 @@ module CPP-TRANSLATION-DECL-DECLARATOR
707714
rule <k> setTrThis(C:Class :: _, methodInfo(... cvQuals: Q::Quals)) => .K ...</k>
708715
<tr-this> _ => pre(This(), hasTrace(This()), type(pointerType(t(Q::Quals, .Set, classType(C))))) </tr-this>
709716

710-
syntax Expr ::= getDefaultReturnOp(QualId, CPPType) [function]
717+
syntax Expr ::= getDefaultReturnOp(Int, QualId, CPPType) [function]
711718

712-
rule getDefaultReturnOp(GlobalNamespace() :: Identifier("main"), T::CPPType)
713-
=> le(temp(!I:Int, type(int)), noTrace, T) :=init prv(0, noTrace, type(int))
719+
rule getDefaultReturnOp(I::Int, GlobalNamespace() :: Identifier("main"), T::CPPType)
720+
=> le(temp(I, type(int)), noTrace, T) :=init prv(0, noTrace, type(int))
714721

715-
rule getDefaultReturnOp(_, _) => prv(voidVal, noTrace, type(void)) [owise]
722+
rule getDefaultReturnOp(_, _, _) => prv(voidVal, noTrace, type(void)) [owise]
716723

717724
syntax KItem ::= dummyBind(List)
718725

semantics/cpp/language/translation/expr/function-call.k

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module CPP-TRANSLATION-EXPR-FUNCTION-CALL
88
imports CPP-DYNAMIC-SYNTAX
99
imports CPP-TRANSLATION-ELABORATOR-SYNTAX
1010
imports CPP-TRANSLATION-OVERLOADING-SYNTAX
11+
imports CPP-TRANSLATION-TEMPORARY-SYNTAX
1112
imports CPP-SYNTAX
1213
imports CPP-TYPING-SYNTAX
1314

@@ -38,7 +39,7 @@ module CPP-TRANSLATION-EXPR-FUNCTION-CALL
3839
syntax List ::= bindParams(List, List, List) [function]
3940

4041
rule bindParams(ListItem(T:CPPType) P::List, ListItem(Init::Init) A::List, ListItem(_) DArgs::List)
41-
=> ListItem(figureInit(le(temp(!I:Int, T), noTrace, T), T, Init, CopyInit(), AutoStorage)) bindParams(P, A, DArgs)
42+
=> ListItem(createTemporary(temp(!I:Int, T), T, figureInit(le(temp(!I:Int, T), noTrace, T), T, Init, CopyInit(), AutoStorage))) bindParams(P, A, DArgs)
4243

4344
// ignore implicit object parameter for static function member
4445
rule bindParams(ListItem(implicitObjectParameter(t(... st: no-type))) P::List,

0 commit comments

Comments
 (0)