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
struct
EscapeState
;Groups global state for escape checking together
-
Declaration
static void
reset
();Called by
initDMD
/deinitializeDMD
toreset
global state
-
-
Declaration
bool
checkMutableArguments
(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*
sc
used to determine current function and module
FuncDeclaration
fd
function being called
TypeFunction
tf
fd
's typeExpression
ethis
if not
null
, thethis
pointerExpressions*
arguments
actual
arguments
to functionbool
gag
do not print error messages
Return Value
true
if error -
Declaration
bool
checkArrayLiteralEscape
(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*
sc
used to determine current function and module
ArrayLiteralExp
ae
array literal expression
bool
gag
do not print error messages
Return Value
true
if any elements escaped -
Declaration
bool
checkAssocArrayLiteralEscape
(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*
sc
used to determine current function and module
AssocArrayLiteralExp
ae
associative array literal expression
bool
gag
do not print error messages
Return Value
true
if any elements escaped -
Declaration
void
printScopeFailure
(E)(EprintFunc
, VarDeclarationv
, intrecursionLimit
);A
scope
variable was assigned to non-scope parameter
. If applicable, print why the parameter was not inferredv
scope
.Parameters
E
printFunc
error/deprecation print function to use
VarDeclaration
v
parameter that was not inferred
int
recursionLimit
recursion limit for printing the reason
-
Declaration
bool
checkParamArgumentEscape
(Scope*sc
, FuncDeclarationfdc
, IdentifierparId
, VarDeclarationvPar
, STCparStc
, Expressionarg
, boolassertmsg
, boolgag
);Function parameter
par
is being initialized to
, andarg
par
may escape. Detect if scoped values can escape this way. Print error messages when these are detected.Parameters
Scope*
sc
used to determine current function and module
FuncDeclaration
fdc
function being called,
null
if called indirectlyIdentifier
parId
name of function parameter for error messages
VarDeclaration
vPar
VarDeclaration
corresponding topar
STC
parStc
storage classes of function parameter (may have added
scope
frompure
)Expression
arg
initializer for param
bool
assertmsg
true
if the parameter is the msg argument to assert(bool, msg).bool
gag
do not print error messages
Return Value
true
if pointers to the stack can escape via assignment -
Declaration
bool
checkParamArgumentReturn
(Scope*sc
, ExpressionfirstArg
, Expressionarg
, Parameterparam
, boolgag
);Function argument initializes a
return
parameter, and that parameter gets assigned to
. Essentially, treat asfirstArg
firstArg
=arg
;Parameters
Scope*
sc
used to determine current function and module
Expression
firstArg
ref
argument through which
may be assignedarg
Expression
arg
initializer for parameter
Parameter
param
parameter declaration corresponding to
arg
bool
gag
do not print error messages
Return Value
true
if assignment to
would cause an errorfirstArg
-
Declaration
bool
checkConstructorEscape
(Scope*sc
, CallExpce
, boolgag
);Check struct constructor of the form
s.this(args)
, by checking eachreturn
parameter to see if it gets assigned tos
.Parameters
Scope*
sc
used to determine current function and module
CallExp
ce
constructor call of the form
s.this(args)
bool
gag
do not print error messages
Return Value
true
if construction would cause an escaping reference error -
Declaration
bool
checkAssignEscape
(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. Inferscope
attribute for the lvalue where possible, in order to eliminate the error.Parameters
Scope*
sc
used to determine current function and module
Expression
e
AssignExp
orCatAssignExp
to check for any pointers to the stackbool
gag
do not print error messages
bool
byRef
set to
true
ife1
of
gets assigned a reference toe
e2
Return Value
true
if pointers to the stack can escape via assignment -
Declaration
bool
checkThrowEscape
(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.e
Parameters
Scope*
sc
used to determine current function and module
Expression
e
expression to check for any pointers to the stack
bool
gag
do not print error messages
Return Value
true
if pointers to the stack can escape -
Declaration
bool
checkNewEscape
(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*
sc
used to determine current function and module
Expression
e
expression to check for any pointers to the stack
bool
gag
do not print error messages
Return Value
true
if pointers to the stack can escape -
Declaration
bool
checkReturnEscape
(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.e
Parameters
Scope*
sc
used to determine current function and module
Expression
e
expression to check for any pointers to the stack
bool
gag
do not print error messages
Return Value
true
if pointers to the stack can escape -
Declaration
bool
checkReturnEscapeRef
(Scope*sc
, Expressione
, boolgag
);Detect cases where returning
bye
ref
can result in a reference to the stack being returned. Print error messages when these are detected.Parameters
Scope*
sc
used to determine current function and module
Expression
e
expression to check
bool
gag
do not print error messages
Return Value
true
if references to the stack can escape -
Declaration
bool
inferScope
(VarDeclarationva
);Infer
scope
for a variableParameters
VarDeclaration
va
variable to infer scope for
Return Value
true
if succesful or alreadyscope
-
Declaration
void
escapeByValue
(Expressione
, EscapeByResults*er
, boollive
= false, boolretRefTransition
= false);e
is an expression to be returned by value, and that value contains pointers. Walke
to determine which variables are possibly being returned by value, such as: int* function(int* p) { return p; } Ife
is 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
Expression
e
expression to be returned by value
EscapeByResults*
er
where to place collected data
bool
live
if @
live
semantics apply, i.e
. expressionsp
,*p
,**p
, etc., all returnp
.bool
retRefTransition
if
is returned through ae
return ref scope
function call -
Declaration
void
escapeByRef
(Expressione
, EscapeByResults*er
, boollive
= false, boolretRefTransition
= false);e
is an expression to be returned by 'ref'. Walke
to determine which variables are possibly being returned by ref, such as: ref int function(int i) { return i; } Ife
is 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
Expression
e
expression to be returned by 'ref'
EscapeByResults*
er
where to place collected data
bool
live
if @
live
semantics apply, i.e
. expressionsp
,*p
,**p
, etc., all returnp
.bool
retRefTransition
if
is returned through ae
return ref scope
function call -
Declaration
struct
EscapeByResults
;Aggregate the data collected by the escapeBy??() functions.
-
Declaration
void
reset
();Reset arrays so the storage can be used again
-
Declaration
void
pushRef
(VarDeclarationv
, boolretRefTransition
);Escape variable
by referencev
Parameters
VarDeclaration
v
variable to escape
bool
retRefTransition
is escaped through av
return ref scope
function call -
Declaration
void
pushExp
(Expressione
, boolretRefTransition
);Escape a reference to expression
e
Parameters
Expression
e
expression to escape
bool
retRefTransition
is escaped through ae
return ref scope
function call
-
-
Declaration
void
findAllOuterAccessedVariables
(FuncDeclarationfd
, VarDeclarations*vars
);Find all variables accessed by this delegate that are in functions enclosing it.
Parameters
FuncDeclaration
fd
function
VarDeclarations*
vars
array to append found variables to
-
Declaration
void
finishScopeParamInference
(FuncDeclarationfuncdecl
, ref TypeFunctionf
);After semantic analysis of the function body, try to infer
scope
/return
on the parametersParameters
FuncDeclaration
funcdecl
function declaration that was analyzed
TypeFunction
f
final function type.
started as the 'premature type' before attribute inference, then its inferred attributes are copied over to final typefuncdecl
.typef
-
Declaration
bool
isReferenceToMutable
(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
Type
t
type of the argument
Return Value
true
if it's a pointer (or reference) to mutable data -
Declaration
bool
isReferenceToMutable
(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
Parameter
p
Parameter to check
Type
t
type of corresponding argument
Return Value
true
if it's a pointer (or reference) to mutable data