From e876ed17ab2cd55f05659324f3b3560ee5bd42a2 Mon Sep 17 00:00:00 2001 From: Xuejun Yang Date: Thu, 17 Nov 2011 12:45:54 -0700 Subject: [PATCH] Fixes for defects reported by Pascal Cuoq. Xuejun says: "Lhs.cpp is for fixing the first issue reported by Pascal; FactUnion.cpp is for fixing the 2nd and 3rd issues. I have run 100,000 test cases for regression test." `Lhs::make_random()': Handle certain cases in which unsigned bitfields are undesirable. `FactUnion::abstract_fact_for_assign()': If writing to an union field is uncertain (due to dereference of a pointer which may points to a union field or something else), mark the union as unreadable. --- src/FactUnion.cpp | 14 ++++++++++---- src/Lhs.cpp | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/FactUnion.cpp b/src/FactUnion.cpp index 554066c1c..594b6dec3 100644 --- a/src/FactUnion.cpp +++ b/src/FactUnion.cpp @@ -70,8 +70,8 @@ FactUnion::get_last_written_type(void) const { assert(var->type && var->type->eType == eUnion); if (is_top() || is_bottom()) return NULL; - assert (last_written_fid >= 0 && last_written_fid < (int)(var->type->fields.size())); - return var->type->fields[last_written_fid]; + assert (last_written_fid >= 0 && last_written_fid < (int)(var->field_vars.size())); + return var->field_vars[last_written_fid]->type; } std::vector @@ -133,8 +133,14 @@ FactUnion::abstract_fact_for_assign(const std::vector& facts, const for (size_t i=0; iis_union_field()) { - fu = make_fact(v->field_var_of, v->get_field_id()); + if (v->is_union_field()) { + if (lvars.size() > 1) { + // if writing to an union field is uncertain (due to dereference of a pointer which may points to an + // union field or something else), We mark the union as unreadable + fu = make_fact(v->field_var_of, BOTTOM); + } else { + fu = make_fact(v->field_var_of, v->get_field_id()); + } } else if (v->is_inside_union_field() && (v->type->has_padding() || v->is_packed_after_bitfield())) { fu = make_fact(v->get_container_union(), BOTTOM); } diff --git a/src/Lhs.cpp b/src/Lhs.cpp index 19787db76..bd0104270 100644 --- a/src/Lhs.cpp +++ b/src/Lhs.cpp @@ -97,7 +97,8 @@ Lhs::make_random(CGContext &cg_context, const Type* t, const CVQualifiers* qfer, assert(var); bool valid = FactPointTo::opportunistic_validate(var, t, fm->global_facts) && !cg_context.get_effect_stm().is_written(var); // we don't want signed integer for some operations, such as ++/-- which has potential of overflowing - if (valid && t->eType == eSimple && no_signed_overflow && var->type->get_base_type()->is_signed()) { + // it's possible for unsigned bitfield to overflow: consider a 31-bit unsigned field that is promoted to 32-bit signed int before arithematics + if (valid && t->eType == eSimple && no_signed_overflow && (var->type->get_base_type()->is_signed() || var->isBitfield_)) { valid = false; } if (valid) {