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
Compiler implementation of the D programming language.
Authors:

Source ob.d

void oblive(FuncDeclaration funcdecl);
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
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
BitArray kill;
which variables in ObState.vars get their state replaced by gen
BitArray comb;
which variables in ObState.vars get their state combined with gen
PtrVarState[] gen;
new states generated by exp
PtrVarState[] input;
variable states on entry to exp
PtrVarState[] output;
variable states on exit to exp
enum PtrState: ubyte;
Pointer variable states:
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;
Lent owner, not usuable while [b] is active
Readonly scope const pointer, copied from [p]
T* p = initializer; scope const(T)* cp = p;
View owner, const while [cp] is active
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

Return O,V: Error, should be undefined

Merge Two Branches:
U O B L C V U U O E O B E E B L E L E L C E E C E C V E V E E E V

E error

const(char)* toChars(PtrState state);
struct PtrVarState;
Carries the state of a pointer variable.
BitArray deps;
dependencies
PtrState state;
state the pointer variable is in
void print(VarDeclaration[] vars);
void depsToBuf(ref OutBuffer buf, const VarDeclaration[] vars);
Produce a user-readable comma separated string of the dependencies.
Parameters:
OutBuffer buf write resulting string here
VarDeclaration[] vars array from which to get the variable names
void setLabelStatementExtraFields(DsymbolTable labtab);
Set the .extra field for LabelStatements in labtab[].
void toObNodes(ref ObNodes obnodes, Statement s);
Convert statement into ObNodes.
void insertFinallyBlockCalls(ref ObNodes obnodes);
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 obnodes graph of the function
void insertFinallyBlockGotos(ref ObNodes obnodes);
Remove try-finally scaffolding.
Parameters:
ObNodes obnodes nodes for the function
void numberNodes(ref ObNodes obnodes);
Set the index field of each ObNode to its index in the array.
void removeUnreachable(ref ObNodes obnodes);
Remove unreachable nodes and compress them out of obnodes[].
Parameters:
ObNodes obnodes array of nodes
void computePreds(ref ObNodes obnodes);
Compute predecessors.
bool isTrackableVar(VarDeclaration v);
Are we interested in tracking this variable?
VarDeclaration isTrackableVarExp(Expression e);
Are we interested in tracking this expression?
Returns:
variable if so, null if not
void collectVars(FuncDeclaration funcdecl, out VarDeclarations vars);
Find the pointer variable declarations in this function, and fill vars with them.
Parameters:
FuncDeclaration funcdecl function we are in
VarDeclarations vars array 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 ObState obstate);
Allocate state variables foreach node.
bool isBorrowedPtr(VarDeclaration v);
Does v meet the definiton of a Borrowed pointer?
Returns:
true if it does
bool isReadonlyPtr(VarDeclaration v);
Does v meet the definiton of a Readonly pointer?
Returns:
true if it does
void computeGenKill(ref ObState obstate);
Compute the gen/comb/kill vectors for each node.
PtrState toPtrState(VarDeclaration v);
Determine the state of a variable based on its type and storage class.
void doDataFlowAnalysis(ref ObState obstate);
Do the data flow analysis (i.e. compute the input[] and output[] vectors for each node).
void checkObErrors(ref ObState obstate);
Check for Ownership/Borrowing errors.