dmd.escape

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

Authors

Walter Bright

Source: escape.d

  • Declaration

    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

    Return Value

    true if error

  • Declaration

    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

    Return Value

    true if any elements escaped

  • Declaration

    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

    Return Value

    true if any elements escaped

  • Declaration

    bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, 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

    Parameter par

    function parameter (this if null)

    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, 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

    Return Value

    true if assignment to firstArg would cause an error

  • Declaration

    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

    Return Value

    true if construction would cause an escaping reference error

  • Declaration

    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

    Return Value

    true if pointers to the stack can escape via assignment

  • Declaration

    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

    Return Value

    true if pointers to the stack can escape

  • Declaration

    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

    Return Value

    true if pointers to the stack can escape

  • Declaration

    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

    Return Value

    true if pointers to the stack can escape

  • Declaration

    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

    Return Value

    true if references to the stack can escape

  • Declaration

    void escapeByValue(Expression e, EscapeByResults* er, bool live = 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; }

    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. expressions p, *p, **p, etc., all return p.

  • Declaration

    void escapeByRef(Expression e, EscapeByResults* er, bool live = false);

    e is an expression to be returned by 'ref'. Walk e to determine which variables are possibly being returned by ref, such as: ref int function(int i) { return i; } If e 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. expressions p, *p, **p, etc., all return p.

  • 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 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

  • Declaration

    void notMaybeScope(VarDeclaration v);

    Turn off STC.maybescope for variable v.

    Discussion

    This exists in order to find where STC.maybescope is getting turned off.

    Parameters

    VarDeclaration v

    variable

  • Declaration

    void eliminateMaybeScopes(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 array elements that cannot be scope.

    Discussion

    Parameters

    VarDeclaration[] array

    array of variables that were assigned to from maybescope variables

  • Declaration

    bool isReferenceToMutable(Type t);

    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(Parameter p, Type t);

    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