Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

dmd.escape

Most of the logic to implement scoped pointers and scoped references is here.
Authors:

Source escape.d

struct EscapeState;
Groups global state for escape checking together
static void reset();
Called by initDMD / deinitializeDMD to reset global state
bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf, Expression ethis, Expressions* arguments, bool gag);
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 type
Expression ethis if not null, the this pointer
Expressions* arguments actual arguments to function
bool gag do not print error messages
Returns:
true if error
bool checkArrayLiteralEscape(Scope* sc, ArrayLiteralExp ae, bool gag);
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
Returns:
true if any elements escaped
bool checkAssocArrayLiteralEscape(Scope* sc, AssocArrayLiteralExp ae, bool gag);
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
Returns:
true if any elements escaped
bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId, VarDeclaration vPar, STC parStc, Expression arg, bool assertmsg, bool gag);
Function parameter par is being initialized to arg, and 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 indirectly
Identifier parId name of function parameter for error messages
VarDeclaration vPar VarDeclaration corresponding to par
STC parStc storage classes of function parameter (may have added scope from pure)
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
Returns:
true if pointers to the stack can escape via assignment
bool checkParamArgumentReturn(Scope* sc, Expression firstArg, Expression arg, Parameter param, bool gag);
Function argument initializes a return parameter, and that parameter gets assigned to firstArg. Essentially, treat as firstArg = arg;
Parameters:
Scope* sc used to determine current function and module
Expression firstArg ref argument through which arg may be assigned
Expression arg initializer for parameter
Parameter param parameter declaration corresponding to arg
bool gag do not print error messages
Returns:
true if assignment to firstArg would cause an error
bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag);
Check struct constructor of the form s.this(args), by checking each return parameter to see if it gets assigned to s.
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
Returns:
true if construction would cause an escaping reference error
enum ReturnParamDest: int;
How a return parameter escapes its pointer value
returnVal
through return statement: return x
this_
assigned to a struct instance: this.x = x
firstArg
assigned to first argument: firstArg = x
ReturnParamDest returnParamDest(TypeFunction tf, Type tthis);
Find out if instead of returning a return parameter via a return statement, it is returned via assignment to either this or the first parameter.
This works the same as returning the value via a return statement. Although the first argument must be ref, it is not regarded as returning by ref.
Parameters:
TypeFunction tf function type
Type tthis type of this parameter, or null if none
Returns:
What a return parameter should transfer the lifetime of the argument to
bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef);
Given an AssignExp, determine if the lvalue will cause the contents of the rvalue to escape. Print error messages when these are detected. Infer scope 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 or CatAssignExp to check for any pointers to the stack
bool gag do not print error messages
bool byRef set to true if e1 of e gets assigned a reference to e2
Returns:
true if pointers to the stack can escape via assignment
bool checkThrowEscape(Scope* sc, Expression e, bool gag);
Detect cases where pointers to the stack can escape the lifetime of the stack frame when throwing e. 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
Returns:
true if pointers to the stack can escape
bool checkNewEscape(Scope* sc, Expression e, bool gag);
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
Returns:
true if pointers to the stack can escape
bool checkReturnEscape(Scope* sc, Expression e, bool gag);
Detect cases where pointers to the stack can escape the lifetime of the stack frame by returning e by value. 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
Returns:
true if pointers to the stack can escape
bool checkReturnEscapeRef(Scope* sc, Expression e, bool gag);
Detect cases where returning e by 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
Returns:
true if references to the stack can escape
void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool retRefTransition = false);
e is an expression to be returned by value, and that value contains pointers. Walk e to determine which variables are possibly being returned by value, such as: int* function(int* p) { return p; } If e 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; }
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. expressions p, *p, **p, etc., all return p.
bool retRefTransition if e is returned through a return ref scope function call
struct EscapeByResults;
Aggregate the data collected by the escapeBy??() functions.
void reset();
Reset arrays so the storage can be used again
void pushRef(VarDeclaration v, bool retRefTransition);
Escape variable v by reference
Parameters:
VarDeclaration v variable to escape
bool retRefTransition v is escaped through a return ref scope function call
void pushExp(Expression e, bool retRefTransition);
Escape a reference to expression e
Parameters:
Expression e expression to escape
bool retRefTransition e is escaped through a return ref scope function call
void findAllOuterAccessedVariables(FuncDeclaration fd, 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
void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f);
After semantic analysis of the function body, try to infer scope / return on the parameters
Parameters:
FuncDeclaration funcdecl function declaration that was analyzed
TypeFunction f final function type. funcdecl.type started as the 'premature type' before attribute inference, then its inferred attributes are copied over to final type f