Improve accuracy of unmodified variable check

This commit is contained in:
Hackerpilot 2015-05-29 08:45:27 -07:00
parent f6dde09c57
commit 7e0d0dd130
1 changed files with 22 additions and 4 deletions

View File

@ -59,7 +59,7 @@ class UnmodifiedFinder:BaseAnalyzer
if (initializedFromCast(d.initializer)) if (initializedFromCast(d.initializer))
continue; continue;
tree[$ - 1].insert(new VariableInfo(d.name.text, d.name.line, tree[$ - 1].insert(new VariableInfo(d.name.text, d.name.line,
d.name.column)); d.name.column, isValueTypeSimple(dec.type)));
} }
} }
dec.accept(this); dec.accept(this);
@ -89,7 +89,9 @@ class UnmodifiedFinder:BaseAnalyzer
if (assignExpression.operator != tok!"") if (assignExpression.operator != tok!"")
{ {
interest++; interest++;
guaranteeUse++;
assignExpression.ternaryExpression.accept(this); assignExpression.ternaryExpression.accept(this);
guaranteeUse--;
interest--; interest--;
assignExpression.assignExpression.accept(this); assignExpression.assignExpression.accept(this);
} }
@ -133,10 +135,13 @@ class UnmodifiedFinder:BaseAnalyzer
override void visit(const UnaryExpression unary) override void visit(const UnaryExpression unary)
{ {
if (unary.prefix == tok!"++" || unary.prefix == tok!"--" if (unary.prefix == tok!"++" || unary.prefix == tok!"--"
|| unary.suffix == tok!"++" || unary.suffix == tok!"--") || unary.suffix == tok!"++" || unary.suffix == tok!"--"
|| unary.prefix == tok!"*" || unary.prefix == tok!"&")
{ {
interest++; interest++;
guaranteeUse++;
unary.accept(this); unary.accept(this);
guaranteeUse--;
interest--; interest--;
} }
else else
@ -168,10 +173,14 @@ private:
void variableMightBeModified(string name) void variableMightBeModified(string name)
{ {
// import std.stdio : stderr;
// stderr.writeln("Marking ", name, " as possibly modified");
size_t index = tree.length - 1; size_t index = tree.length - 1;
auto vi = VariableInfo(name); auto vi = VariableInfo(name);
if (guaranteeUse == 0)
{
auto r = tree[index].equalRange(&vi);
if (!r.empty && r.front.isValueType)
return;
}
while (true) while (true)
{ {
if (tree[index].removeKey(&vi) != 0 || index == 0) if (tree[index].removeKey(&vi) != 0 || index == 0)
@ -236,6 +245,7 @@ private:
string name; string name;
size_t line; size_t line;
size_t column; size_t column;
bool isValueType;
} }
void popScope() void popScope()
@ -260,8 +270,16 @@ private:
int interest; int interest;
int guaranteeUse;
int isImmutable; int isImmutable;
RedBlackTree!(VariableInfo*, "a.name < b.name")[] tree; RedBlackTree!(VariableInfo*, "a.name < b.name")[] tree;
} }
bool isValueTypeSimple(const Type type) pure nothrow @nogc
{
if (type.type2 is null)
return false;
return type.type2.builtinType != tok!"" && type.typeSuffixes.length == 0;
}