Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Calendar
  - Forums
  - IRC
  - Community Discord
  - Wiki
  - GitHub
  - Issues
  - Get involved
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
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:
Walter Bright
License:
Boost License 1.0

Source escape.d

Documentation https://dlang.org/phobos/dmd_escape.html

Coverage https://codecov.io/gh/dlang/dmd/src/master/src/dmd/escape.d

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

  Returns:
  true if pointers to the stack can escape via assignment
bool `checkParamArgumentReturn`(Scope* `sc`, Expression `firstArg`, Expression `arg`, 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
  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
bool `checkAssignEscape`(Scope* `sc`, Expression `e`, bool `gag`);
  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

  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);
  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.

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; }
  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.

struct `EscapeByResults`;
  Aggregate the data collected by the escapeBy??() functions.
  void `reset`();
    Reset arrays so the storage can be used again
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 `notMaybeScope`(VarDeclaration `v`);
  Turn off STC.maybescope for variable `v`.
  This exists in order to find where STC.maybescope is getting turned off.
  Parameters:

  VarDeclaration `v` | variable

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.

  Scope Table
  va | v | => | va | v
  --- | --- | --- | --- | ---
  maybe | maybe | => | scope | scope
  scope | scope | => | scope | scope
  scope | maybe | => | scope | scope
  maybe | scope | => | scope | scope
  - | - | => | - | -
  - | maybe | => | - | -
  - | scope | => | error | error
  maybe | - | => | scope | -
  scope | - | => | scope | -

  Parameters:

  VarDeclaration[] `array` | array of variables that were assigned to from maybescope variables

bool `isReferenceToMutable`(Type `t`);
  Is type a reference to a mutable value?
  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

  Returns:
  true if it's a pointer (or reference) to mutable data
bool `isReferenceToMutable`(Parameter `p`, Type `t`);
  Is parameter a reference to a mutable value?
  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

  Returns:
  true if it's a pointer (or reference) to mutable data

Copyright © 1999-2020 by the D Language Foundation | Page generated by Ddoc on Mon May 11 10:58:05 2020