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
structEscapeState;Groups global state for escape checking together
-
Declaration
static voidreset();Called by
initDMD/deinitializeDMDtoresetglobal state
-
-
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
voidprintScopeFailure(E)(EprintFunc, VarDeclarationv, intrecursionLimit);A
scopevariable was assigned to non-scope parameter. If applicable, print why the parameter was not inferredvscope.Parameters
EprintFuncerror/deprecation print function to use
VarDeclarationvparameter that was not inferred
intrecursionLimitrecursion limit for printing the reason
-
Declaration
boolcheckParamArgumentEscape(Scope*sc, FuncDeclarationfdc, Parameterpar, VarDeclarationvPar, STCparStc, 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)VarDeclarationvParVarDeclarationcorresponding toparSTCparStcstorage classes of function parameter (may have added
scopefrompure)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
boolinferScope(VarDeclarationva);Infer
scopefor a variableParameters
VarDeclarationvavariable to infer scope for
Return Value
trueif succesful or alreadyscope -
Declaration
voidescapeByValue(Expressione, EscapeByResults*er, boollive= false, boolretRefTransition= 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.boolretRefTransitionif
is returned through aereturn ref scopefunction call -
Declaration
voidescapeByRef(Expressione, EscapeByResults*er, boollive= false, boolretRefTransition= 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.boolretRefTransitionif
is returned through aereturn ref scopefunction call -
Declaration
structEscapeByResults;Aggregate the data collected by the escapeBy??() functions.
-
Declaration
voidreset();Reset arrays so the storage can be used again
-
Declaration
voidpushRef(VarDeclarationv, boolretRefTransition);Escape variable
by referencevParameters
VarDeclarationvvariable to escape
boolretRefTransitionis escaped through avreturn ref scopefunction call -
Declaration
voidpushExp(Expressione, boolretRefTransition);Escape a reference to expression
eParameters
Expressioneexpression to escape
boolretRefTransitionis escaped through aereturn ref scopefunction call
-
-
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
voidfinishScopeParamInference(FuncDeclarationfuncdecl, ref TypeFunctionf);After semantic analysis of the function body, try to infer
scope/returnon the parametersParameters
FuncDeclarationfuncdeclfunction declaration that was analyzed
TypeFunctionffinal function type.
started as the 'premature type' before attribute inference, then its inferred attributes are copied over to final typefuncdecl.typef -
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