dmd.escape
Most of the logic to implement scoped pointers and scoped references is here.
License
Source: escape.d
Documentation: https://dlang.org/phobos/dmd_escape.html
-
Declaration
boolcheckMutableArguments(Scope*sc, FuncDeclarationfd, TypeFunctiontf, Expressionethis, Expressions*arguments, boolgag);Checks memory objects passed to a function. Checks that if a memory object is passed by ref or by pointer, all of the refs or pointers are const, or there is only one mutable ref or pointer to it.
References: DIP 1021
Parameters
Scope*scused to determine current function and module
FuncDeclarationfdfunction being called
TypeFunctiontffd's typeExpressionethisif not
null, thethispointerExpressions*argumentsactual
argumentsto functionboolgagdo not print error messages
Return Value
trueif error -
Declaration
boolcheckArrayLiteralEscape(Scope*sc, ArrayLiteralExpae, boolgag);Array literal is going to be allocated on the GC heap. Check its elements to see if any would escape by going on the heap.
Parameters
Scope*scused to determine current function and module
ArrayLiteralExpaearray literal expression
boolgagdo not print error messages
Return Value
trueif any elements escaped -
Declaration
boolcheckAssocArrayLiteralEscape(Scope*sc, AssocArrayLiteralExpae, boolgag);Associative array literal is going to be allocated on the GC heap. Check its elements to see if any would escape by going on the heap.
Parameters
Scope*scused to determine current function and module
AssocArrayLiteralExpaeassociative array literal expression
boolgagdo not print error messages
Return Value
trueif any elements escaped -
Declaration
boolcheckParamArgumentEscape(Scope*sc, FuncDeclarationfdc, Parameterpar, Expressionarg, boolassertmsg, boolgag);Function parameter
is being initialized topar, andargmay escape. Detect if scoped values can escape this way. Print error messages when these are detected.parParameters
Scope*scused to determine current function and module
FuncDeclarationfdcfunction being called,
nullif called indirectlyParameterparfunction parameter (
thisifnull)Expressionarginitializer for param
boolassertmsgtrueif the parameter is the msg argument to assert(bool, msg).boolgagdo not print error messages
Return Value
trueif pointers to the stack can escape via assignment -
Declaration
boolcheckParamArgumentReturn(Scope*sc, ExpressionfirstArg, Expressionarg, Parameterparam, boolgag);Function argument initializes a
returnparameter, and that parameter gets assigned to. Essentially, treat asfirstArgfirstArg=arg;Parameters
Scope*scused to determine current function and module
ExpressionfirstArgrefargument through whichmay be assignedargExpressionarginitializer for parameter
Parameterparamparameter declaration corresponding to
argboolgagdo not print error messages
Return Value
trueif assignment towould cause an errorfirstArg -
Declaration
boolcheckConstructorEscape(Scope*sc, CallExpce, boolgag);Check struct constructor of the form
s.this(args), by checking eachreturnparameter to see if it gets assigned tos.Parameters
Scope*scused to determine current function and module
CallExpceconstructor call of the form
s.this(args)boolgagdo not print error messages
Return Value
trueif construction would cause an escaping reference error -
Declaration
boolcheckAssignEscape(Scope*sc, Expressione, boolgag, boolbyRef);Given an
AssignExp, determine if the lvalue will cause the contents of the rvalue to escape. Print error messages when these are detected. Inferscopeattribute for the lvalue where possible, in order to eliminate the error.Parameters
Scope*scused to determine current function and module
ExpressioneAssignExporCatAssignExpto check for any pointers to the stackboolgagdo not print error messages
boolbyRefset to
trueife1ofgets assigned a reference toee2Return Value
trueif pointers to the stack can escape via assignment -
Declaration
boolcheckThrowEscape(Scope*sc, Expressione, boolgag);Detect cases where pointers to the stack can escape the lifetime of the stack frame when throwing
. Print error messages when these are detected.eParameters
Scope*scused to determine current function and module
Expressioneexpression to check for any pointers to the stack
boolgagdo not print error messages
Return Value
trueif pointers to the stack can escape -
Declaration
boolcheckNewEscape(Scope*sc, Expressione, boolgag);Detect cases where pointers to the stack can escape the lifetime of the stack frame by being placed into a GC allocated object. Print error messages when these are detected.
Parameters
Scope*scused to determine current function and module
Expressioneexpression to check for any pointers to the stack
boolgagdo not print error messages
Return Value
trueif pointers to the stack can escape -
Declaration
boolcheckReturnEscape(Scope*sc, Expressione, boolgag);Detect cases where pointers to the stack can escape the lifetime of the stack frame by returning
by value. Print error messages when these are detected.eParameters
Scope*scused to determine current function and module
Expressioneexpression to check for any pointers to the stack
boolgagdo not print error messages
Return Value
trueif pointers to the stack can escape -
Declaration
boolcheckReturnEscapeRef(Scope*sc, Expressione, boolgag);Detect cases where returning
byerefcan result in a reference to the stack being returned. Print error messages when these are detected.Parameters
Scope*scused to determine current function and module
Expressioneexpression to check
boolgagdo not print error messages
Return Value
trueif references to the stack can escape -
Declaration
voidescapeByValue(Expressione, EscapeByResults*er, boollive= false);eis an expression to be returned by value, and that value contains pointers. Walketo determine which variables are possibly being returned by value, such as: int* function(int* p) { return p; } Ifeis a form of &p, determine which variables have content which is being returned as ref, such as: int* function(int i) { return &i; } Multiple variables can be inserted, because of expressions like this: int function(bool b, int i, int* p) { return b ? &i : p; }Discussion
No side effects.
Parameters
Expressioneexpression to be returned by value
EscapeByResults*erwhere to place collected data
boolliveif @
livesemantics apply, i.e. expressionsp,*p,**p, etc., all returnp. -
Declaration
voidescapeByRef(Expressione, EscapeByResults*er, boollive= false);eis an expression to be returned by 'ref'. Walketo determine which variables are possibly being returned by ref, such as: ref int function(int i) { return i; } Ifeis a form of p, determine which variables have content which is being returned as ref, such as: ref int function(int) p { return p; } Multiple variables can be inserted, because of expressions like this: ref int function(bool b, int i, int) p { return b ? i : *p; }Discussion
No side effects.
Parameters
Expressioneexpression to be returned by 'ref'
EscapeByResults*erwhere to place collected data
boolliveif @
livesemantics apply, i.e. expressionsp,*p,**p, etc., all returnp. -
Declaration
structEscapeByResults;Aggregate the data collected by the escapeBy??() functions.
-
Declaration
voidreset();Reset arrays so the storage can be used again
-
-
Declaration
voidfindAllOuterAccessedVariables(FuncDeclarationfd, VarDeclarations*vars);Find all variables accessed by this delegate that are in functions enclosing it.
Parameters
FuncDeclarationfdfunction
VarDeclarations*varsarray to append found variables to
-
Declaration
voidnotMaybeScope(VarDeclarationv);Turn off
STC.maybescopefor variable.vDiscussion
This exists in order to find where
STC.maybescopeis getting turned off.Parameters
VarDeclarationvvariable
-
Declaration
voideliminateMaybeScopes(VarDeclaration[]array);Have some variables that are maybescopes that were assigned values from other maybescope variables. Now that semantic analysis of the function is complete, we can finalize this by turning off maybescope for
arrayelements that cannot be scope.Discussion
Parameters
VarDeclaration[]arrayarrayof variables that were assigned to from maybescope variables -
Declaration
boolisReferenceToMutable(Typet);Is type a reference to a mutable value?
Discussion
This is used to determine if an argument that does not have a corresponding Parameter, i.e. a variadic argument, is a pointer to mutable data.
Parameters
Typettype of the argument
Return Value
trueif it's a pointer (or reference) to mutable data -
Declaration
boolisReferenceToMutable(Parameterp, Typet);Is parameter a reference to a mutable value?
Discussion
This is used if an argument has a corresponding Parameter. The argument type is necessary if the Parameter is inout.
Parameters
ParameterpParameter to check
Typettype of corresponding argument
Return Value
trueif it's a pointer (or reference) to mutable data