@@ -1781,112 +1781,15 @@ bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr)
1781
1781
}
1782
1782
}
1783
1783
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)
1786
1788
return true ;
1787
1789
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 ;
1890
1793
}
1891
1794
1892
1795
bool simplify_exprt::simplify_byte_update (byte_update_exprt &expr)
0 commit comments