Fixed handling of invalid array access in mem2reg code
authorClifford Wolf <clifford@clifford.at>
Wed, 15 Oct 2014 22:44:23 +0000 (00:44 +0200)
committerClifford Wolf <clifford@clifford.at>
Wed, 15 Oct 2014 22:44:23 +0000 (00:44 +0200)
frontends/ast/ast.h
frontends/ast/simplify.cc

index 0a4016736350372cb1679468fc1c06bbeb017fb7..56f5d888dafe33179015c776aab6ed0262a013ab 100644 (file)
@@ -209,6 +209,7 @@ namespace AST
                void mem2reg_as_needed_pass1(std::map<AstNode*, std::set<std::string>> &mem2reg_places,
                                std::map<AstNode*, uint32_t> &mem2reg_flags, std::map<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags);
                void mem2reg_as_needed_pass2(std::set<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block);
+               bool mem2reg_check(std::set<AstNode*> &mem2reg_set);
                void meminfo(int &mem_width, int &mem_size, int &addr_bits);
 
                // additional functionality for evaluating constant functions
index 9f33ea780555abdd5342fc15e8864134ca8c4b75..7e15283c41e7a26510cacfab74425b1db8048104 100644 (file)
@@ -2179,14 +2179,25 @@ void AstNode::mem2reg_as_needed_pass1(std::map<AstNode*, std::set<std::string>>
        }
 }
 
+bool AstNode::mem2reg_check(std::set<AstNode*> &mem2reg_set)
+{
+       if (type != AST_IDENTIFIER || !id2ast || !mem2reg_set.count(id2ast))
+               return false;
+
+       if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1)
+               log_error("Invalid array access at %s:%d.\n", filename.c_str(), linenum);
+
+       return true;
+}
+
 // actually replace memories with registers
 void AstNode::mem2reg_as_needed_pass2(std::set<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block)
 {
        if (type == AST_BLOCK)
                block = this;
 
-       if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && block != NULL && children[0]->id2ast &&
-                       mem2reg_set.count(children[0]->id2ast) > 0 && children[0]->children[0]->children[0]->type != AST_CONSTANT)
+       if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && block != NULL &&
+                       children[0]->mem2reg_check(mem2reg_set) && children[0]->children[0]->children[0]->type != AST_CONSTANT)
        {
                std::stringstream sstr;
                sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
@@ -2242,7 +2253,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set<AstNode*> &mem2reg_set, AstNode *
                type = AST_ASSIGN_EQ;
        }
 
-       if (type == AST_IDENTIFIER && id2ast && mem2reg_set.count(id2ast) > 0)
+       if (mem2reg_check(mem2reg_set))
        {
                AstNode *bit_part_sel = NULL;
                if (children.size() == 2)