Bug 871075 - Add rooting analysis warnings for unsafe address taken of variables DONTBUILD

This commit is contained in:
Brian Hackett 2013-05-22 07:47:41 -06:00
parent 2c2722d303
commit 8bbd38036f
2 changed files with 70 additions and 0 deletions

View File

@ -109,6 +109,35 @@ function edgeUsesVariable(edge, variable)
} }
} }
function expressionIsVariableAddress(exp, variable)
{
while (exp.Kind == "Fld")
exp = exp.Exp[0];
return exp.Kind == "Var" && sameVariable(exp.Variable, variable);
}
function edgeTakesVariableAddress(edge, variable)
{
if (ignoreEdgeUse(edge, variable))
return false;
if (ignoreEdgeAddressTaken(edge))
return false;
switch (edge.Kind) {
case "Assign":
return expressionIsVariableAddress(edge.Exp[1], variable);
case "Call":
if ("PEdgeCallArguments" in edge) {
for (var exp of edge.PEdgeCallArguments.Exp) {
if (expressionIsVariableAddress(exp, variable))
return true;
}
}
return false;
default:
return false;
}
}
function edgeKillsVariable(edge, variable) function edgeKillsVariable(edge, variable)
{ {
// Direct assignments kill their lhs. // Direct assignments kill their lhs.
@ -326,6 +355,21 @@ function variableLiveAcrossGC(variable)
return null; return null;
} }
function unsafeVariableAddressTaken(variable)
{
for (var body of functionBodies) {
if (!("PEdge" in body))
continue;
for (var edge of body.PEdge) {
if (edgeTakesVariableAddress(edge, variable)) {
if (edge.Kind == "Assign" || edgeCanGC(edge))
return {body:body, ppoint:edge.Index[0]};
}
}
}
return null;
}
function computePrintedLines() function computePrintedLines()
{ {
assert(!system("xdbfind src_body.xdb '" + functionName + "' > " + tmpfile)); assert(!system("xdbfind src_body.xdb '" + functionName + "' > " + tmpfile));
@ -474,6 +518,14 @@ function processBodies()
" at " + lineText); " at " + lineText);
printEntryTrace(result.why); printEntryTrace(result.why);
} }
result = unsafeVariableAddressTaken(variable.Variable);
if (result) {
var lineText = findLocation(result.body, result.ppoint);
print("\nFunction '" + functionName + "'" +
" takes unsafe address of unrooted '" + name + "'" +
" at " + lineText);
printEntryTrace({body:result.body, ppoint:result.ppoint});
}
} }
} }
} }

View File

@ -106,6 +106,24 @@ function ignoreEdgeUse(edge, variable)
return false; return false;
} }
function ignoreEdgeAddressTaken(edge)
{
// Functions which may take indirect pointers to unrooted GC things,
// but will copy them into rooted locations before calling anything
// that can GC. These parameters should usually be replaced with
// handles or mutable handles.
if (edge.Kind == "Call") {
var callee = edge.Exp[0];
if (callee.Kind == "Var") {
var name = callee.Variable.Name[0];
if (/js::Invoke\(/.test(name))
return true;
}
}
return false;
}
// Ignore calls of these functions (so ignore any stack containing these) // Ignore calls of these functions (so ignore any stack containing these)
var ignoreFunctions = { var ignoreFunctions = {
"ptio.c:pt_MapError" : true, "ptio.c:pt_MapError" : true,