@@ -1802,111 +1802,15 @@ bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr)
18021802 }
18031803 }
18041804
1805- // rethink the remaining code to correctly handle big endian
1806- if (expr.id ()!=ID_byte_extract_little_endian)
1805+ // try to refine it down to extracting from a member or an index in an array
1806+ exprt subexpr =
1807+ get_subexpression_at_offset (expr.op (), offset, expr.type (), expr.id (), ns);
1808+ if (subexpr.is_nil () || subexpr == expr)
18071809 return true ;
18081810
1809- // get type of object
1810- const typet &op_type=ns.follow (expr.op ().type ());
1811-
1812- if (op_type.id ()==ID_array)
1813- {
1814- exprt result=expr.op ();
1815-
1816- // try proper array or string constant
1817- for (const typet *op_type_ptr=&op_type;
1818- op_type_ptr->id ()==ID_array;
1819- op_type_ptr=&(ns.follow (*op_type_ptr).subtype ()))
1820- {
1821- // no arrays of zero-sized objects
1822- assert (el_size>0 );
1823- // no arrays of non-byte sized objects
1824- assert (el_size%8 ==0 );
1825- mp_integer el_bytes=el_size/8 ;
1826-
1827- if (base_type_eq (expr.type (), op_type_ptr->subtype (), ns) ||
1828- (expr.type ().id ()==ID_pointer &&
1829- op_type_ptr->subtype ().id ()==ID_pointer))
1830- {
1831- if (offset%el_bytes==0 )
1832- {
1833- offset/=el_bytes;
1834-
1835- result=
1836- index_exprt (
1837- result,
1838- from_integer (offset, expr.offset ().type ()));
1839- result.make_typecast (expr.type ());
1840-
1841- if (!base_type_eq (expr.type (), op_type_ptr->subtype (), ns))
1842- result.make_typecast (expr.type ());
1843-
1844- expr.swap (result);
1845- simplify_rec (expr);
1846- return false ;
1847- }
1848- }
1849- else
1850- {
1851- mp_integer sub_size=pointer_offset_size (op_type_ptr->subtype (), ns);
1852-
1853- if (sub_size>0 )
1854- {
1855- mp_integer index=offset/sub_size;
1856- offset%=sub_size;
1857-
1858- result=
1859- index_exprt (
1860- result,
1861- from_integer (index, expr.offset ().type ()));
1862- }
1863- }
1864- }
1865- }
1866- else if (op_type.id ()==ID_struct)
1867- {
1868- const struct_typet &struct_type=
1869- to_struct_type (op_type);
1870- const struct_typet::componentst &components=
1871- struct_type.components ();
1872-
1873- mp_integer m_offset_bits=0 ;
1874- for (const auto &component : components)
1875- {
1876- mp_integer m_size=
1877- pointer_offset_bits (component.type (), ns);
1878- if (m_size<=0 )
1879- break ;
1880-
1881- if (offset*8 ==m_offset_bits &&
1882- el_size==m_size &&
1883- base_type_eq (expr.type (), component.type (), ns))
1884- {
1885- member_exprt member (expr.op (), component.get_name (), component.type ());
1886- simplify_member (member);
1887- expr.swap (member);
1888-
1889- return false ;
1890- }
1891- else if (offset*8 >=m_offset_bits &&
1892- offset*8 +el_size<=m_offset_bits+m_size &&
1893- m_offset_bits%8 ==0 )
1894- {
1895- expr.op ()=
1896- member_exprt (expr.op (), component.get_name (), component.type ());
1897- simplify_member (expr.op ());
1898- expr.offset ()=
1899- from_integer (offset-m_offset_bits/8 , expr.offset ().type ());
1900- simplify_rec (expr);
1901-
1902- return false ;
1903- }
1904-
1905- m_offset_bits+=m_size;
1906- }
1907- }
1908-
1909- return true ;
1811+ simplify_rec (subexpr);
1812+ expr.swap (subexpr);
1813+ return false ;
19101814}
19111815
19121816bool simplify_exprt::simplify_byte_update (byte_update_exprt &expr)
0 commit comments