Uninit
rascal-0.40.17
Synopsis
Find unitialized variables in a Pico program.
Examples
Uninitialized variables are variables that are used without being initialized. This means that there is a path in the control flow graph from the entry point of the program to a specific use of a variable, where that path does not contain a definition of that variable.
This can be computed as follows:
module demo::lang::Pico::Uninit
import demo::lang::Pico::Abstract;
import demo::lang::Pico::Load;
import demo::lang::Pico::UseDef;
import demo::lang::Pico::ControlFlow;
import analysis::graphs::Graph;
set[CFNode] defNodes(PicoId Id, set[Occurrence] Defs) =
{statement(occ.stat.src, occ.stat) | Occurrence occ <- Defs, occ.name == Id};
set[Occurrence] uninitProgram(PROGRAM P) {
D = defs(P); ❶
CFG = cflowProgram(P); ❶
return { occ | occ <- uses(P),
any(CFNode N <- reachX(CFG.graph, CFG.entry, defNodes(occ.name, D)),
N has location && occ.src <= N.location)
};
}
set[Occurrence] uninitProgram(str txt) = uninitProgram(load(txt));
caution
There is a "TODO" in the documentation source: :this description does not fit the example anymore (((TODO:this description does not fit the example anymore)))
- ❶ First, we determine the variable definitions of the program, and its control flow graph.
- ❷ Next we ask for every use of a variable the question: can it be reached from the entries
of the program without encountering a definition? This determined as follows:
rangeR(D, {occ.item})
is the set of definition for the variable were are looking at. See RangeR.reachX
determines the reachability in a graph while excluding certain nodes, see Graph-reachX. HerereachX(CFG.graph, CFG.entry, rangeR(D, {occ.item}))
determines the nodes in the graph that can be reached from the entry point of the program without passing a definition of the current variable.any(CFNode N <- reachX( ... ), N has location && occ.location \<= N.location)
yields true if there is such a reachable node that covers the location of the current variable.
- ❸ The complete comprehension returns the set of occurrences of uninitialized variables.
The function uninitProgram
performs this analysis on the source text of a Pico program.
Here is a simple example, where variable p
is used without intialization:
rascal>import demo::lang::Pico::Uninit;
ok
rascal>uninitProgram("begin declare n : natural, m : natural, p : natural; n := 10; m := n + p end");
rel[loc src,str name,STATEMENT stat]: {<|unknown:///|(71,1,<1,71>,<1,72>),"p",asgStat(
"m",
add(
id(
"n",
src=|unknown:///|(67,1,<1,67>,<1,68>),
comments=()),
id(
"p",
src=|unknown:///|(71,1,<1,71>,<1,72>),
comments=()),
src=|unknown:///|(67,5,<1,67>,<1,72>),
comments=()),
src=|unknown:///|(62,10,<1,62>,<1,72>),
comments=())>}