diff --git a/src/ArrayVariable.cpp b/src/ArrayVariable.cpp index 854d0b7c8..30e1c16b7 100644 --- a/src/ArrayVariable.cpp +++ b/src/ArrayVariable.cpp @@ -186,7 +186,7 @@ ArrayVariable::ArrayVariable(Block* blk, const std::string &name, const Type *ty } ArrayVariable::ArrayVariable(const ArrayVariable& av) - : Variable(av.name, av.type, av.init, &(av.qfer), av.isFieldVarOf_, true), + : Variable(av.name, av.type, av.init, &(av.qfer), av.field_var_of, true), collective(av.collective), parent(av.parent), sizes(av.sizes), diff --git a/src/CGContext.cpp b/src/CGContext.cpp index ef37c74da..0c70740ad 100644 --- a/src/CGContext.cpp +++ b/src/CGContext.cpp @@ -376,14 +376,14 @@ CGContext::read_indices(const Variable* v, const vector& facts) return false; } } - if (av->isFieldVarOf_) { - return read_indices(av->isFieldVarOf_, facts); + if (av->field_var_of) { + return read_indices(av->field_var_of, facts); } return true; } else if (v->is_array_field()) { // find the parent that is an array - for (; v && !v->isArray; v = v->isFieldVarOf_) { + for (; v && !v->isArray; v = v->field_var_of) { /* Empty. */ } assert(v); diff --git a/src/Effect.cpp b/src/Effect.cpp index 99f1145d8..ec5131630 100644 --- a/src/Effect.cpp +++ b/src/Effect.cpp @@ -292,8 +292,8 @@ Effect::is_read(const Variable *v) const // however we can not say the same thing for unions: reading a particular // unions field can cause unspecified behaviors, while reading the whole // union won't - if (v->isFieldVarOf_ && v->isFieldVarOf_->type->eType == eStruct) { - return is_read(v->isFieldVarOf_); + if (v->field_var_of && v->field_var_of->type->eType == eStruct) { + return is_read(v->field_var_of); } return false; } @@ -354,8 +354,8 @@ Effect::is_written(const Variable *v) const } } // if we write a struct/union, presumingly all the fields are written too - if (v->isFieldVarOf_) { - return is_written(v->isFieldVarOf_); + if (v->field_var_of) { + return is_written(v->field_var_of); } return false; } @@ -440,18 +440,18 @@ Effect::field_is_written(const Variable *v) const bool Effect::sibling_union_field_is_read(const Variable *v) const { - while (v->isFieldVarOf_) { + while (v->field_var_of) { // check other fields of the union - if (v->isFieldVarOf_->type->eType == eUnion) { - for (size_t j=0; jisFieldVarOf_->field_vars.size(); j++) { - Variable* field_var = v->isFieldVarOf_->field_vars[j]; + if (v->field_var_of->type->eType == eUnion) { + for (size_t j=0; jfield_var_of->field_vars.size(); j++) { + Variable* field_var = v->field_var_of->field_vars[j]; if (field_var == v) continue; if (is_read(field_var) || field_is_read(field_var)) { return true; } } } - v = v->isFieldVarOf_; + v = v->field_var_of; } return false; } @@ -459,18 +459,18 @@ Effect::sibling_union_field_is_read(const Variable *v) const bool Effect::sibling_union_field_is_written(const Variable *v) const { - while (v->isFieldVarOf_) { + while (v->field_var_of) { // check other fields of the union - if (v->isFieldVarOf_->type->eType == eUnion) { - for (size_t j=0; jisFieldVarOf_->field_vars.size(); j++) { - Variable* field_var = v->isFieldVarOf_->field_vars[j]; + if (v->field_var_of->type->eType == eUnion) { + for (size_t j=0; jfield_var_of->field_vars.size(); j++) { + Variable* field_var = v->field_var_of->field_vars[j]; if (field_var == v) continue; if (is_written(field_var) || field_is_written(field_var)) { return true; } } } - v = v->isFieldVarOf_; + v = v->field_var_of; } return false; } @@ -497,7 +497,7 @@ Effect::consolidate(void) size_t len = read_vars.size(); for (i=0; iis_field_var() && is_read(tmp->isFieldVarOf_)) { + if (tmp->is_field_var() && is_read(tmp->field_var_of)) { read_vars.erase(read_vars.begin() + i); i--; len--; @@ -506,7 +506,7 @@ Effect::consolidate(void) len = write_vars.size(); for (i=0; iis_field_var() && is_written(tmp->isFieldVarOf_)) { + if (tmp->is_field_var() && is_written(tmp->field_var_of)) { write_vars.erase(write_vars.begin() + i); i--; len--; diff --git a/src/FactPointTo.cpp b/src/FactPointTo.cpp index 3a4cdd275..46b1e213c 100644 --- a/src/FactPointTo.cpp +++ b/src/FactPointTo.cpp @@ -719,12 +719,10 @@ FactPointTo::update_with_modified_index(const Variable* index_var) const size_t j, k; vector pointees = point_to_vars; bool changed = false; - if (index_var->name == "p_4") - j = 0; for (j=0; jisFieldVarOf_) { - v = v->isFieldVarOf_; + while (v->field_var_of) { + v = v->field_var_of; } // if v is an itemized array variable, check it's indices if (v->isArray && v->get_collective() != v) { diff --git a/src/FactUnion.cpp b/src/FactUnion.cpp index 32d7d6bd0..be6328b0f 100644 --- a/src/FactUnion.cpp +++ b/src/FactUnion.cpp @@ -122,7 +122,7 @@ FactUnion::abstract_fact_for_assign(const std::vector& facts, const const Variable* v = lvars[i]; const FactUnion* fu = 0; if (v->is_union_field()) { - fu = make_fact(v->isFieldVarOf_, v->get_field_id()); + fu = make_fact(v->field_var_of, v->get_field_id()); } if (fu) { ret_facts.push_back(fu); @@ -179,7 +179,7 @@ bool FactUnion::is_nonreadable_field(const Variable *v, const std::vector& facts) { if (v->is_union_field()) { - FactUnion tmp(v->isFieldVarOf_, v->get_field_id()); + FactUnion tmp(v->field_var_of, v->get_field_id()); const FactUnion* fu = dynamic_cast(find_related_fact(facts, &tmp)); if (fu && !tmp.imply(*fu)) { return true; diff --git a/src/Variable.cpp b/src/Variable.cpp index f2b3fa1f5..ab3d65a8b 100644 --- a/src/Variable.cpp +++ b/src/Variable.cpp @@ -191,8 +191,8 @@ void remove_field_vars(vector& set) for (i=0; iis_field_var()) { - while (v->isFieldVarOf_) { - v = v->isFieldVarOf_; + while (v->field_var_of) { + v = v->field_var_of; } set.erase(set.begin() + i); add_variable_to_set(set, v); @@ -204,7 +204,7 @@ void remove_field_vars(vector& set) /* * examples: array[0] "loose matches" array[1]; array[3] "loose matches" array[x].f1... - * union.f1 "loose matches" union.f2 + * union.f1 "loose matches" union.f2.f3 */ bool Variable::loose_match(const Variable* v) const @@ -214,10 +214,12 @@ Variable::loose_match(const Variable* v) const if (me->match(you)) { return true; } - if (me->isFieldVarOf_== you->isFieldVarOf_ && me->is_union_field()) { - return true; - } - return false; + // find the union variable(s) that contain me and you + for (me = me->field_var_of; me && me->type->eType != eUnion; me = me->field_var_of) + ; + for (you = you->field_var_of; you && you->type->eType != eUnion; you = you->field_var_of) + ; + return you && me && (you == me); } /* @@ -246,8 +248,8 @@ Variable::get_seq_num(void) const bool Variable::is_array_field(void) const { - if (isFieldVarOf_) { - return isFieldVarOf_->is_array_field(); + if (field_var_of) { + return field_var_of->is_array_field(); } return isArray; } @@ -258,8 +260,8 @@ Variable::is_array_field(void) const bool Variable::is_virtual(void) const { - if (isFieldVarOf_) { - return isFieldVarOf_->is_virtual(); + if (field_var_of) { + return field_var_of->is_virtual(); } if (isArray) { return ((const ArrayVariable*)this)->collective==0; @@ -278,7 +280,7 @@ bool Variable::has_field_var(const Variable* v) const if (tmp == this) { return true; } - tmp = tmp->isFieldVarOf_; + tmp = tmp->field_var_of; } } return false; @@ -287,9 +289,9 @@ bool Variable::has_field_var(const Variable* v) const int Variable::get_field_id(void) const { - if (isFieldVarOf_) { - for (size_t i=0; ifield_vars.size(); i++) { - if (isFieldVarOf_->field_vars[i] == this) { + if (field_var_of) { + for (size_t i=0; ifield_vars.size(); i++) { + if (field_var_of->field_vars[i] == this) { return i; } } @@ -389,7 +391,7 @@ Variable::Variable(const std::string &name, const Type *type, : name(name), type(type), init(0), isAuto(isAuto), isStatic(isStatic), isRegister(isRegister), - isBitfield_(isBitfield), isFieldVarOf_(isFieldVarOf), isArray(false), + isBitfield_(isBitfield), field_var_of(isFieldVarOf), isArray(false), qfer(isConsts, isVolatiles) { // nothing else to do @@ -401,7 +403,7 @@ Variable::Variable(const std::string &name, const Type *type, Variable::Variable(const std::string &name, const Type *type, const Expression* init, const CVQualifiers* qfer) : name(name), type(type), init(init), - isAuto(false), isStatic(false), isRegister(false), isBitfield_(false), isFieldVarOf_(0), isArray(false), + isAuto(false), isStatic(false), isRegister(false), isBitfield_(false), field_var_of(0), isArray(false), qfer(*qfer) { // nothing else to do @@ -411,7 +413,7 @@ Variable::Variable(const std::string &name, const Type *type, const Expression* : name(name), type(type), init(init), isAuto(false), isStatic(false), isRegister(false), isBitfield_(false), - isFieldVarOf_(isFieldVarOf), + field_var_of(isFieldVarOf), isArray(isArray), qfer(*qfer) { @@ -439,7 +441,7 @@ bool Variable::is_global(void) const { if (is_field_var()) { - return isFieldVarOf_->is_global(); + return field_var_of->is_global(); } return (name.find("g_") == 0); } @@ -452,7 +454,7 @@ Variable::is_visible_local(const Block* blk) const return is_global(); } if (is_field_var()) { - return isFieldVarOf_->is_visible_local(blk); + return field_var_of->is_visible_local(blk); } size_t i; const Function* func = blk->func; @@ -615,8 +617,8 @@ Variable::deputy_annotation(void) const anno = oss.str(); } //if (pointee->is_array_field()) { - // while (pointee->isFieldVarOf_) { - // pointee = pointee->isFieldVarOf_; + // while (pointee->field_var_of) { + // pointee = pointee->field_var_of; // } // assert(pointee->isArray); //} @@ -658,8 +660,8 @@ Variable::get_collective(void) const // special handling for array fields if (is_array_field()) { // find top-level parent, which should be an array - const Variable* parent = isFieldVarOf_; - for (; parent && !parent->isArray; parent = parent->isFieldVarOf_) { + const Variable* parent = field_var_of; + for (; parent && !parent->isArray; parent = parent->field_var_of) { /* Empty. */ } assert(parent); @@ -691,8 +693,8 @@ const Variable* Variable::get_named_var(void) const { const Variable* v = this; - while (v->isFieldVarOf_) { - v = v->isFieldVarOf_; + while (v->field_var_of) { + v = v->field_var_of; } return v->get_collective(); } @@ -703,8 +705,8 @@ Variable::get_array(string& field) const // special handling for array fields if (is_array_field()) { // find top-level parent, which should be an array - const Variable* parent = isFieldVarOf_; - for (; parent && !parent->isArray; parent = parent->isFieldVarOf_) { + const Variable* parent = field_var_of; + for (; parent && !parent->isArray; parent = parent->field_var_of) { /* Empty. */ } assert(parent); @@ -811,8 +813,8 @@ Variable::output_qualified_type(std::ostream &out) const void Variable::OutputUpperBound(std::ostream &out) const { - if (isFieldVarOf_) { - isFieldVarOf_->OutputUpperBound(out); + if (field_var_of) { + field_var_of->OutputUpperBound(out); size_t dot = name.find_last_of("."); assert(dot != string::npos); string postfix = name.substr(dot, string::npos); @@ -827,8 +829,8 @@ Variable::OutputUpperBound(std::ostream &out) const void Variable::OutputLowerBound(std::ostream &out) const { - if (isFieldVarOf_) { - isFieldVarOf_->OutputLowerBound(out); + if (field_var_of) { + field_var_of->OutputLowerBound(out); size_t dot = name.find_last_of("."); assert(dot != string::npos); string postfix = name.substr(dot, string::npos); @@ -1305,6 +1307,24 @@ Variable::match_var_name(const string& vname) const return NULL; } +/* order fields inside a struct/union variable */ +int +Variable::compare_field(const Variable* v) const +{ + if (is_field_var() && v->is_field_var()) { + const Variable* my_base = NULL; + const Variable* your_base = NULL; + for (my_base = this->field_var_of; my_base->field_var_of; my_base = my_base->field_var_of) + ; + for (your_base = v->field_var_of; your_base->field_var_of; your_base = your_base->field_var_of) + ; + if (my_base == your_base) { + return name.compare(v->name); + } + } + return 0; +} + /////////////////////////////////////////////////////////////////////////////// // Local Variables: diff --git a/src/Variable.h b/src/Variable.h index 08b7e4ab3..601c634b2 100644 --- a/src/Variable.h +++ b/src/Variable.h @@ -87,9 +87,9 @@ class Variable bool is_const_after_deref(int deref_level) const; bool is_volatile_after_deref(int deref_level) const; bool has_field_var(const Variable* v) const; - bool is_field_var(void) const { return isFieldVarOf_ != 0; }; + bool is_field_var(void) const { return field_var_of != 0; }; int get_field_id(void) const; - bool is_union_field(void) const { return isFieldVarOf_ != 0 && isFieldVarOf_->type->eType == eUnion; }; + bool is_union_field(void) const { return field_var_of != 0 && field_var_of->type->eType == eUnion; }; bool is_array_field(void) const; bool is_virtual(void) const; bool is_aggregate(void) const { return type && type->is_aggregate(); } @@ -97,6 +97,7 @@ class Variable bool loose_match(const Variable* v) const; bool is_pointer(void) const { return type && type->eType == ePointer;} bool is_rv(void) const { return StringUtils::end_with(name, "_rv"); } + int compare_field(const Variable* v) const; int get_seq_num(void) const; virtual std::string get_actual_name() const; @@ -144,7 +145,7 @@ class Variable const bool isStatic; const bool isRegister; const bool isBitfield_; // expanded from a full-bitfield struct var - const Variable* isFieldVarOf_; //expanded from a struct/union + const Variable* field_var_of; //expanded from a struct/union const bool isArray; const CVQualifiers qfer; static std::vector ctrl_vars; diff --git a/src/VariableSelector.cpp b/src/VariableSelector.cpp index 284a7e16e..b8553b514 100644 --- a/src/VariableSelector.cpp +++ b/src/VariableSelector.cpp @@ -1349,9 +1349,21 @@ VariableSelector::itemize_array(CGContext& cg_context, const ArrayVariable* av) map::iterator iter; for(iter = cg_context.iv_bounds.begin(); iter != cg_context.iv_bounds.end(); ++iter) { if (iter->second != INVALID_BOUND && iter->second < dimen_len) { - ok_ivs.push_back(iter->first); + const Variable* iv = iter->first; + // unfortunately different std::map implementations give us diff. order, we + // have to sort them to generate consistant outputs across diff. platforms + bool insert_middle = false; + for (size_t j=0; jcompare_field(iv) > 0) { + ok_ivs.insert(ok_ivs.begin() + j, iv); + insert_middle = true; + break; + } + } + if (!insert_middle) ok_ivs.push_back(iv); } - } + } + const Variable* v = choose_ok_var(ok_ivs); // this could happen if the context contained 2 or more array to be used, but the longer one(s) has // been removed, and leaving the shorter one that is too short for the induction variable's range