Skip to content

Commit 044b004

Browse files
committed
Use get_subexpression_at_offset in simplify_byte_extract
1 parent fa0d4f6 commit 044b004

File tree

3 files changed

+11
-106
lines changed

3 files changed

+11
-106
lines changed

src/pointer-analysis/value_set_dereference.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Author: Daniel Kroening, [email protected]
2929
#include <util/options.h>
3030
#include <util/pointer_offset_size.h>
3131
#include <util/pointer_predicates.h>
32+
#include <util/simplify_expr.h>
3233
#include <util/ssa_expr.h>
3334

3435
// global data, horrible
@@ -471,6 +472,8 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
471472
// try to build a member/index expression - do not use byte_extract
472473
exprt subexpr = get_subexpression_at_offset(
473474
root_object_subexpression, o.offset(), dereference_type, ns);
475+
if(subexpr.is_not_nil())
476+
simplify(subexpr, ns);
474477
if(subexpr.is_not_nil() && subexpr.id() != byte_extract_id())
475478
{
476479
// Successfully found a member, array index, or combination thereof

src/util/pointer_offset_size.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,12 +722,11 @@ exprt get_subexpression_at_offset(
722722
}
723723
}
724724

725-
const byte_extract_exprt be(
725+
return byte_extract_exprt(
726726
byte_extract_id(),
727727
expr,
728728
from_integer(offset_bytes, index_type()),
729729
target_type_raw);
730-
return simplify_expr(be, ns);
731730
}
732731

733732
exprt get_subexpression_at_offset(

src/util/simplify_expr.cpp

Lines changed: 7 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,112 +1781,15 @@ bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr)
17811781
}
17821782
}
17831783

1784-
// rethink the remaining code to correctly handle big endian
1785-
if(expr.id()!=ID_byte_extract_little_endian)
1784+
// try to refine it down to extracting from a member or an index in an array
1785+
exprt subexpr =
1786+
get_subexpression_at_offset(expr.op(), offset, expr.type(), ns);
1787+
if(subexpr.is_nil() || subexpr == expr)
17861788
return true;
17871789

1788-
// get type of object
1789-
const typet &op_type=ns.follow(expr.op().type());
1790-
1791-
if(op_type.id()==ID_array)
1792-
{
1793-
exprt result=expr.op();
1794-
1795-
// try proper array or string constant
1796-
for(const typet *op_type_ptr=&op_type;
1797-
op_type_ptr->id()==ID_array;
1798-
op_type_ptr=&(ns.follow(*op_type_ptr).subtype()))
1799-
{
1800-
DATA_INVARIANT(*el_size > 0, "arrays must not have zero-sized objects");
1801-
DATA_INVARIANT(
1802-
(*el_size) % 8 == 0,
1803-
"array elements have a size in bits which is a multiple of bytes");
1804-
1805-
mp_integer el_bytes = (*el_size) / 8;
1806-
1807-
if(base_type_eq(expr.type(), op_type_ptr->subtype(), ns) ||
1808-
(expr.type().id()==ID_pointer &&
1809-
op_type_ptr->subtype().id()==ID_pointer))
1810-
{
1811-
if(offset%el_bytes==0)
1812-
{
1813-
offset/=el_bytes;
1814-
1815-
result=
1816-
index_exprt(
1817-
result,
1818-
from_integer(offset, expr.offset().type()));
1819-
result.make_typecast(expr.type());
1820-
1821-
if(!base_type_eq(expr.type(), op_type_ptr->subtype(), ns))
1822-
result.make_typecast(expr.type());
1823-
1824-
expr.swap(result);
1825-
simplify_rec(expr);
1826-
return false;
1827-
}
1828-
}
1829-
else
1830-
{
1831-
auto sub_size = pointer_offset_size(op_type_ptr->subtype(), ns);
1832-
1833-
if(sub_size.has_value() && *sub_size > 0)
1834-
{
1835-
mp_integer index = offset / (*sub_size);
1836-
offset %= (*sub_size);
1837-
1838-
result=
1839-
index_exprt(
1840-
result,
1841-
from_integer(index, expr.offset().type()));
1842-
}
1843-
}
1844-
}
1845-
}
1846-
else if(op_type.id()==ID_struct)
1847-
{
1848-
const struct_typet &struct_type=
1849-
to_struct_type(op_type);
1850-
const struct_typet::componentst &components=
1851-
struct_type.components();
1852-
1853-
mp_integer m_offset_bits=0;
1854-
for(const auto &component : components)
1855-
{
1856-
auto m_size = pointer_offset_bits(component.type(), ns);
1857-
if(!m_size.has_value() || *m_size <= 0)
1858-
break;
1859-
1860-
if(
1861-
offset * 8 == m_offset_bits && *el_size == *m_size &&
1862-
base_type_eq(expr.type(), component.type(), ns))
1863-
{
1864-
member_exprt member(expr.op(), component.get_name(), component.type());
1865-
simplify_member(member);
1866-
expr.swap(member);
1867-
1868-
return false;
1869-
}
1870-
else if(
1871-
offset * 8 >= m_offset_bits &&
1872-
offset * 8 + *el_size <= m_offset_bits + *m_size &&
1873-
m_offset_bits % 8 == 0)
1874-
{
1875-
expr.op()=
1876-
member_exprt(expr.op(), component.get_name(), component.type());
1877-
simplify_member(expr.op());
1878-
expr.offset()=
1879-
from_integer(offset-m_offset_bits/8, expr.offset().type());
1880-
simplify_rec(expr);
1881-
1882-
return false;
1883-
}
1884-
1885-
m_offset_bits += *m_size;
1886-
}
1887-
}
1888-
1889-
return true;
1790+
simplify_rec(subexpr);
1791+
expr.swap(subexpr);
1792+
return false;
18901793
}
18911794

18921795
bool simplify_exprt::simplify_byte_update(byte_update_exprt &expr)

0 commit comments

Comments
 (0)