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.ob
Flow analysis for Ownership/Borrowing
Authors:
License:
Source ob.d
Documentation https://dlang.org/phobos/dmd_escape.html
References https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md Argument Ownership and Function Calls
- void
oblive(FuncDeclarationfuncdecl); - Perform ownership/borrowing checks for funcdecl. Does not modify the AST, just checks for errors.
- struct
ObState; - Collect the state information.
- Array!size_t
varStack; - temporary storage
- Array!bool
mutableStack; - parallel to varStack[], is type mutable?
- PtrVarState[]
varPool; - memory pool
- struct
ObNode; - A node in the function's expression graph, and its edges to predecessors and successors.
- Expression
exp; - expression for the node
- ObNodes
preds; - predecessors
- ObNodes
succs; - successors
- ObNode*
tryBlock; - try-finally block we're inside
- uint
index; - index of this in obnodes
- PtrVarState[]
gen; - new states generated for this node
- PtrVarState[]
input; - variable states on entry to exp
- PtrVarState[]
output; - variable states on exit to exp
- enum
PtrState: ubyte; - Pointer variable states:Initial state is not known; ignore for now Undefined not in a usable state T* p = void; Owner mutable pointer T* p = initializer; Borrowed scope mutable pointer, borrowed from [p] T* p = initializer; scope T* b = p; Readonly scope const pointer, copied from [p] T* p = initializer; scope const(T)* cp = p;Examples:T* p = initializer; // p is owner T** pp = &p; // pp borrows from p T* p = initialize; // p is owner T* q = p; // transfer: q is owner, p is undefined
- const(char)*
PtrStateToChars(PtrStatestate); - struct
PtrVarState; - Carries the state of a pointer variable.
- BitArray
deps; - dependencies
- PtrState
state; - state the pointer variable is in
- void
print(VarDeclaration[]vars); - Print a bracketed list of all the variables that depend on 'this'Parameters:
VarDeclaration[] varsvariables that depend on 'this' - void
depsToBuf(ref OutBufferbuf, const VarDeclaration[]vars); - Produce a user-readable comma separated string of the dependencies.Parameters:
OutBuffer bufwrite resulting string here VarDeclaration[] varsarray from which to get the variable names
- void
setLabelStatementExtraFields(DsymbolTablelabtab); - Set the .extra field for LabelStatements in labtab[].
- void
toObNodes(ref ObNodesobnodes, Statements); - Convert statement into ObNodes.
- void
insertFinallyBlockCalls(ref ObNodesobnodes); - Insert finally block calls when doing a goto from inside a try block to outside. Done after blocks are generated because then we know all the edges of the graph, but before the pred's are computed.Parameters:
ObNodes obnodesgraph of the function - void
insertFinallyBlockGotos(ref ObNodesobnodes); - Remove try-finally scaffolding.Parameters:
ObNodes obnodesnodes for the function - @safe void
numberNodes(ref ObNodesobnodes); - Set the index field of each ObNode to its index in the
obnodes[] array. - void
removeUnreachable(ref ObNodesobnodes); - Remove unreachable nodes and compress them out of obnodes[].Parameters:
ObNodes obnodesarray of nodes - void
computePreds(ref ObNodesobnodes); - Compute predecessors.
- bool
isTrackableVar(VarDeclarationv); - Are we interested in tracking variable
v? - VarDeclaration
isTrackableVarExp(Expressione); - Are we interested in tracking this expression?Returns:variable if so, null if not
- void
collectVars(FuncDeclarationfuncdecl, out VarDeclarationsvars); - Find the pointer variable declarations in this function, and fill
varswith them.Parameters:FuncDeclaration funcdeclfunction we are in VarDeclarations varsarray to fill in - void
allocDeps(PtrVarState[]pvss); - Allocate BitArrays in PtrVarState. Can be allocated much more efficiently by subdividing a single large array of bits
- void
allocStates(ref ObStateobstate); - Allocate state variables foreach node.
- bool
isBorrowedPtr(VarDeclarationv); - Does v meet the definiton of a Borrowed pointer?Returns:true if it does
- bool
isReadonlyPtr(VarDeclarationv); - Does v meet the definiton of a Readonly pointer?Returns:true if it does
- void
genKill(ref ObStateobstate, ObNode*ob); - Compute the gen vector for ob.
- PtrState
toPtrState(VarDeclarationv); - Determine the state of a variable based on its type and storage class.
- bool
hasPointersToMutableFields(Typet); - Does type
tcontain any pointers to mutable? - bool
hasMutableFields(Typet); - Does type
thave any mutable fields? - void
doDataFlowAnalysis(ref ObStateobstate); - Do the data flow analysis (i.e. compute the input[] and output[] vectors for each ObNode).
- void
escapeLive(Expressione, scope void delegate(VarDeclaration)onVar); - Check for escaping variables using DIP1000's escapeByValue, with live set to trueParameters:
Expression eexpression to check void delegate(VarDeclaration) onVargets called for each variable escaped through e, either by value or by ref - void
checkObErrors(ref ObStateobstate); - Check for Ownership/Borrowing errors.
- void
readVar(ObNode*ob, const size_tvi, boolmutable, PtrVarState[]gen); - Read from variable vi. The beginning of the 'scope' of a variable is when it is first read. Hence, when a read is done, instead of when assignment to the variable is done, the O/B rules are enforced. (Also called "non-lexical scoping".)
- void
makeChildrenUndefined(size_tvi, PtrVarState[]gen); - Recursively make Undefined all who list vi as a dependency
- void
makeUndefined(size_tvi, PtrVarState[]gen); - Recursively make Undefined vi undefined and all who list vi as a dependencyParameters:
size_t vivariable's index PtrVarState[] genarray of the states of variables - bool
isMutableRef(Typet); - Is type
ta reference to a const or a reference to a mutable?
Copyright © 1999-2025 by the D Language Foundation | Page generated by
Ddoc on Mon Mar 31 10:27:59 2025