From 9bdeb8d433d41140755b56e1dc4384ec06006d5c Mon Sep 17 00:00:00 2001 From: Xuejun Yang Date: Fri, 17 Jun 2011 10:36:19 -0600 Subject: [PATCH] bug fix for union: consider callees when determining if a function reads union field --- src/Function.cpp | 24 +++++++++++++------- src/Function.h | 1 + src/Statement.cpp | 56 +++++++++++++++++++++++++---------------------- src/Statement.h | 2 ++ 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/Function.cpp b/src/Function.cpp index fce783f2d..f9e222494 100644 --- a/src/Function.cpp +++ b/src/Function.cpp @@ -601,21 +601,29 @@ Function::generate_body_with_known_params(const CGContext &prev_context, Effect& ERROR_RETURN(); body->set_depth_protect(true); + compute_summary(); + + make_return_const(); + ERROR_RETURN(); + + // Mark this function as built. + build_state = BUILT; +} + +void +Function::compute_summary(void) +{ + FactMgr* fm = get_fact_mgr_for_func(this); // compute the pointers that are statically referenced in the function // including ones referenced by its callees body->get_referenced_ptrs(referenced_ptrs); - // Compute the function's externally visible effect. Currently, this - // is just the effect on globals. + // Compute the function's externally visible effect. //effect.add_external_effect(*cg_context.get_effect_accum()); feffect.add_external_effect(fm->map_stm_effect[body]); - union_field_read = fm->map_stm_effect[body].union_field_is_read(); - make_return_const(); - ERROR_RETURN(); - - // Mark this function as built. - build_state = BUILT; + // determine whether an union field is read + union_field_read = body->read_union_field(); } /* diff --git a/src/Function.h b/src/Function.h index c7f447512..e664b2614 100644 --- a/src/Function.h +++ b/src/Function.h @@ -78,6 +78,7 @@ class Function static void doFinalization(); void generate_body_with_known_params(const CGContext &prev_context, Effect& effect_accum); + void compute_summary(void); void Output(std::ostream &); void OutputForwardDecl(std::ostream &); diff --git a/src/Statement.cpp b/src/Statement.cpp index d60cd7db3..45a23187e 100644 --- a/src/Statement.cpp +++ b/src/Statement.cpp @@ -51,6 +51,7 @@ #include "Expression.h" #include "ExpressionFuncall.h" #include "FunctionInvocation.h" +#include "FunctionInvocationUser.h" #include "FactPointTo.h" #include "Block.h" // temporary; don't want to depend on subclases! @@ -672,6 +673,24 @@ Statement::is_jump_target_from_other_blocks(void) const return false; } +bool +Statement::read_union_field(void) const +{ + FactMgr* fm = get_fact_mgr_for_func(func); + assert(fm); + if (fm->map_stm_effect[this].union_field_is_read()) { + return true; + } + vector calls; + get_called_funcs(calls); + for (size_t i=0; iget_func()->union_field_read) { + return true; + } + } + return false; +} + /* * return true if s is contained inside this statement */ @@ -750,33 +769,18 @@ Statement::get_direct_invocation(void) const void Statement::get_called_funcs(std::vector& funcs) const { - if (eType == eAssign) { - ((const StatementAssign*)this)->get_rhs()->get_called_funcs(funcs); - } - else if (eType == eInvoke) { - ((const StatementExpr*)this)->get_invoke()->get_called_funcs(funcs); - } - else if (eType == eBlock) { - const Block* b = (const Block*)this; - size_t i; - for (i=0; istms.size(); i++) { - b->stms[i]->get_called_funcs(funcs); - } + size_t i; + vector exprs; + vector blks; + get_exprs(exprs); + get_blocks(blks); + for (i=0; iget_called_funcs(funcs); } - else if (eType == eIfElse) { - const StatementIf* si = (const StatementIf*)this; - si->get_test()->get_called_funcs(funcs); - si->get_true_branch()->get_called_funcs(funcs); - si->get_false_branch()->get_called_funcs(funcs); - } - else if (eType == eFor) { - const StatementFor* sf = (const StatementFor*)this; - sf->get_body()->get_called_funcs(funcs); - } - else if (eType == eArrayOp) { - const StatementArrayOp* sa = (const StatementArrayOp*)this; - if (sa->body) { - sa->body->get_called_funcs(funcs); + for (i=0; istms.size(); j++) { + const Statement* s = blks[i]->stms[j]; + s->get_called_funcs(funcs); } } } diff --git a/src/Statement.h b/src/Statement.h index 4229f2272..99507d931 100644 --- a/src/Statement.h +++ b/src/Statement.h @@ -145,6 +145,8 @@ class Statement bool is_jump_target_from_other_blocks(void) const; + bool read_union_field(void) const; + virtual void get_blocks(std::vector& /* blks */) const = 0; virtual void get_exprs(std::vector& /* exps */) const = 0;