From 78cec1556c85db6beb4f3d9f918b5a1f421719ef Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 12 Nov 2016 18:09:32 +0200 Subject: [PATCH] Fix unused variable decetion for self-referenging assignments Extend it to initialization expressions as well. --- source/programcompiler.cpp | 52 +++++++++++++++++++++++++++++++------- source/programcompiler.h | 3 +++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index 934416c2..55f62ae9 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -627,22 +627,34 @@ void ProgramCompiler::VariableRenamer::visit(VariableDeclaration &var) ProgramCompiler::UnusedVariableLocator::UnusedVariableLocator(): assignment(false), - assignment_target(0) + record_target(false), + assignment_target(0), + indeterminate_target(false), + self_referencing(false) { } void ProgramCompiler::UnusedVariableLocator::visit(VariableReference &var) { - if(assignment) - assignment_target = var.declaration; + if(record_target) + { + if(assignment_target) + indeterminate_target = true; + else + assignment_target = var.declaration; + } else { unused_nodes.erase(var.declaration); + map::iterator i = assignments.find(var.declaration); if(i!=assignments.end()) { unused_nodes.erase(i->second); assignments.erase(i); } + + if(assignment && var.declaration==assignment_target) + self_referencing = true; } } @@ -656,9 +668,20 @@ void ProgramCompiler::UnusedVariableLocator::visit(BinaryExpression &binary) { if(binary.assignment) { - binary.right->visit(*this); assignment = true; + { + SetFlag set(record_target); + binary.left->visit(*this); + } + if(binary.oper!="=") + self_referencing = true; + binary.right->visit(*this); + } + else if(record_target && binary.oper=="[") + { binary.left->visit(*this); + SetForScope set(record_target, false); + binary.right->visit(*this); } else TraversingVisitor::visit(binary); @@ -668,17 +691,21 @@ void ProgramCompiler::UnusedVariableLocator::visit(ExpressionStatement &expr) { assignment = false; assignment_target = 0; + indeterminate_target = false; + self_referencing = false; TraversingVisitor::visit(expr); - if(assignment && assignment_target) + if(assignment && assignment_target && !indeterminate_target) { Node *&assign = assignments[assignment_target]; - if(assign) + if(self_referencing) + unused_nodes.erase(assign); + else if(assign) unused_nodes.insert(assign); assign = &expr; - if(assignment_target->interface!="out" || (stage->type!=FRAGMENT && !assignment_target->linked_declaration)) - unused_nodes.insert(&expr); - else + if(assignment_target->interface=="out" && (stage->type==FRAGMENT || assignment_target->linked_declaration)) unused_nodes.erase(assignment_target); + else + unused_nodes.insert(&expr); } assignment = false; } @@ -686,6 +713,11 @@ void ProgramCompiler::UnusedVariableLocator::visit(ExpressionStatement &expr) void ProgramCompiler::UnusedVariableLocator::visit(VariableDeclaration &var) { unused_nodes.insert(&var); + if(var.init_expression) + { + unused_nodes.insert(&*var.init_expression); + assignments[&var] = &*var.init_expression; + } TraversingVisitor::visit(var); } @@ -731,6 +763,8 @@ void ProgramCompiler::NodeRemover::visit(VariableDeclaration &var) if(var.linked_declaration) var.linked_declaration->linked_declaration = 0; } + else if(var.init_expression && to_remove.count(&*var.init_expression)) + var.init_expression = 0; } void ProgramCompiler::NodeRemover::visit(InterfaceBlock &iface) diff --git a/source/programcompiler.h b/source/programcompiler.h index 34b64b55..f1ea1652 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -100,7 +100,10 @@ private: std::set unused_nodes; std::map assignments; bool assignment; + bool record_target; ProgramSyntax::VariableDeclaration *assignment_target; + bool indeterminate_target; + bool self_referencing; UnusedVariableLocator(); -- 2.43.0