diff --git a/src/Constant.h b/src/Constant.h index 5bea57e28..0f85cd29a 100644 --- a/src/Constant.h +++ b/src/Constant.h @@ -34,6 +34,7 @@ #include #include +#include #include "Expression.h" #include "Type.h" @@ -63,6 +64,8 @@ class Constant : public Expression CVQualifiers get_qualifiers(void) const { return CVQualifiers(true, false);} + virtual void get_eval_to_subexps(vector& subs) const {subs.push_back(this);} + Constant(const Type *t, const std::string &v); explicit Constant(const Constant &c); virtual ~Constant(void); diff --git a/src/Expression.h b/src/Expression.h index 0ad60b132..68026888a 100644 --- a/src/Expression.h +++ b/src/Expression.h @@ -112,6 +112,8 @@ class Expression virtual CVQualifiers get_qualifiers(void) const = 0; + virtual void get_eval_to_subexps(vector& subs) const = 0; + virtual void get_called_funcs(std::vector& /*funcs*/ ) const {}; virtual const FunctionInvocation* get_invoke(void) const {return NULL;}; diff --git a/src/ExpressionAssign.cpp b/src/ExpressionAssign.cpp index 4fb3360a1..056750c9a 100644 --- a/src/ExpressionAssign.cpp +++ b/src/ExpressionAssign.cpp @@ -112,6 +112,14 @@ ExpressionAssign::is_0_or_1(void) const return assign->is_simple_assign() && assign->get_expr()->is_0_or_1(); } +void +ExpressionAssign::get_eval_to_subexps(vector& subs) const +{ + vector exps; + get_lhs()->get_eval_to_subexps(exps); + subs.insert(subs.end(), exps.begin(), exps.end()); +} + bool ExpressionAssign::visit_facts(vector& inputs, CGContext& cg_context) const { diff --git a/src/ExpressionAssign.h b/src/ExpressionAssign.h index 1c2779872..6b3b6c033 100644 --- a/src/ExpressionAssign.h +++ b/src/ExpressionAssign.h @@ -55,6 +55,8 @@ class ExpressionAssign : public Expression virtual CVQualifiers get_qualifiers(void) const; + virtual void get_eval_to_subexps(vector& subs) const; + virtual const Type &get_type(void) const { return assign->get_lhs()->get_type();} virtual void get_called_funcs(std::vector& funcs) const { assign->get_called_funcs(funcs);} diff --git a/src/ExpressionComma.cpp b/src/ExpressionComma.cpp index f065dddfa..94e7759a0 100644 --- a/src/ExpressionComma.cpp +++ b/src/ExpressionComma.cpp @@ -92,6 +92,14 @@ ExpressionComma::get_dereferenced_ptrs(void) const return ptrs1; } +void +ExpressionComma::get_eval_to_subexps(vector& subs) const +{ + vector exps; + get_rhs()->get_eval_to_subexps(exps); + subs.insert(subs.end(), exps.begin(), exps.end()); +} + void ExpressionComma::Output(std::ostream &out) const { diff --git a/src/ExpressionComma.h b/src/ExpressionComma.h index efa21fbc0..b47176437 100644 --- a/src/ExpressionComma.h +++ b/src/ExpressionComma.h @@ -49,6 +49,8 @@ class ExpressionComma : public Expression virtual CVQualifiers get_qualifiers(void) const { return rhs.get_qualifiers();} + virtual void get_eval_to_subexps(vector& subs) const; + virtual const Type &get_type(void) const { return rhs.get_type();} virtual void get_called_funcs(std::vector& funcs) const { lhs.get_called_funcs(funcs); rhs.get_called_funcs(funcs);} diff --git a/src/ExpressionFuncall.h b/src/ExpressionFuncall.h index 229e688be..6da09734b 100644 --- a/src/ExpressionFuncall.h +++ b/src/ExpressionFuncall.h @@ -58,6 +58,8 @@ class ExpressionFuncall : public Expression virtual CVQualifiers get_qualifiers(void) const; + virtual void get_eval_to_subexps(vector& subs) const {subs.push_back(this);} + virtual const FunctionInvocation* get_invoke(void) const { return &invoke; }; virtual const Type &get_type(void) const; diff --git a/src/ExpressionVariable.h b/src/ExpressionVariable.h index 0dc82e91d..1f9865a09 100644 --- a/src/ExpressionVariable.h +++ b/src/ExpressionVariable.h @@ -59,6 +59,8 @@ class ExpressionVariable : public Expression virtual CVQualifiers get_qualifiers(void) const; + virtual void get_eval_to_subexps(vector& subs) const {subs.push_back(this);} + int get_indirect_level(void) const; const Variable* get_var(void) const {return &var;}; diff --git a/src/Lhs.cpp b/src/Lhs.cpp index 651b5df0d..19787db76 100644 --- a/src/Lhs.cpp +++ b/src/Lhs.cpp @@ -328,10 +328,16 @@ Lhs::visit_facts(vector& inputs, CGContext& cg_context) const if (!visit_indices(inputs, cg_context)) { return false; } - // avoid a.x = a.y where x and y are partially overlapping fields - if (cg_context.curr_rhs && cg_context.curr_rhs->term_type == eVariable) { - if (have_overlapping_fields(cg_context.curr_rhs, this, inputs)) { - return false; + // avoid a.x = a.y (or any RHS that evaluates to a.y) where x and y are partially overlapping fields + if (cg_context.curr_rhs) { + vector subs; + cg_context.curr_rhs->get_eval_to_subexps(subs); + for (size_t i=0; iterm_type == eVariable || subs[i]->term_type == eLhs) { + if (have_overlapping_fields(subs[i], this, inputs)) { + return false; + } + } } } diff --git a/src/Lhs.h b/src/Lhs.h index 5d1762b31..615985c0e 100644 --- a/src/Lhs.h +++ b/src/Lhs.h @@ -59,6 +59,8 @@ class Lhs : public Expression virtual CVQualifiers get_qualifiers(void) const; + virtual void get_eval_to_subexps(vector& subs) const {subs.push_back(this);} + int get_indirect_level(void) const; void get_lvars(const vector& facts, vector& vars) const;