Skip to content

Commit 0487376

Browse files
author
Thomas Kiley
authored
Merge pull request diffblue#2173 from svorenova/gs_tg1121
[TG-1121] Bugfix for multi-dimensional arrays with non-const size and non-const access
2 parents 108129c + 6af2270 commit 0487376

File tree

5 files changed

+46
-30
lines changed

5 files changed

+46
-30
lines changed
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
FloatMultidim1.class
33
--function FloatMultidim1.f --cover location --unwind 3
44
\d+ of \d+ covered
55
^EXIT=0$
66
^SIGNAL=0$
7-
--
8-
--
9-
This crashes during symex, with error 'cannot unpack array of nonconst size'
10-
when trying to access the element of the array. Symex uses byte_extract_little
11-
_endian to access the element which does not get simplified (it seems the
12-
problem is that the types in the instruction do not match). TG-1121
7+
y=1$
8+
y=[2-4]$
9+
y=([05-9]|[1-9][0-9]+|-[1-9][0-9]*)$
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
RefMultidim1.class
33
--function RefMultidim1.f --cover location --unwind 3
44
\d+ of \d+ covered
55
^EXIT=0$
66
^SIGNAL=0$
7-
--
8-
--
9-
This crashes during symex, with error 'cannot unpack array of nonconst size'
10-
when trying to access the element of the array. Symex uses byte_extract_little
11-
_endian to access the element which does not get simplified (it seems the
12-
problem is that the types in the instruction do not match). TG-1121
7+
y=1$
8+
y=[2-4]$
9+
y=([05-9]|[1-9][0-9]+|-[1-9][0-9]*)$
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
RefMultidim2.class
33
--function RefMultidim2.f --cover location --unwind 3
44
\d+ of \d+ covered
55
^EXIT=0$
66
^SIGNAL=0$
7-
--
8-
--
9-
This crashes during symex, with error 'cannot unpack array of nonconst size'
10-
when trying to access the element of the array. Symex uses byte_extract_little
11-
_endian to access the element which does not get simplified (it seems the
12-
problem is that the types in the instruction do not match). TG-1121
7+
y=1$
8+
y=[2-4]$
9+
y=([05-9]|[1-9][0-9]+|-[1-9][0-9]*)$
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
CORE
22
TestClass.class
33
--function TestClass.f --cover location --unwind 2
4-
Source GOTO statement: .*
5-
(^ exception: Can't convert byte_extraction|Nested exception printing not supported on Windows)
6-
^EXIT=6$
7-
--
8-
--
9-
The exception thrown in this test is the symptom of a bug; the purpose of this
10-
test is the validate the output of that exception
4+
^EXIT=0$
5+
^SIGNAL=0$

src/pointer-analysis/value_set_dereference.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,38 @@ bool value_set_dereferencet::dereference_type_compare(
201201
const typet &object_type,
202202
const typet &dereference_type) const
203203
{
204-
if(dereference_type.id()==ID_empty)
205-
return true; // always ok
204+
// check if the two types have matching number of ID_pointer levels, with
205+
// the dereference type eventually pointing to void; then this is ok
206+
// for example:
207+
// - dereference_type=void is ok (no matter what object_type is);
208+
// - object_type=(int *), dereference_type=(void *) is ok;
209+
// - object_type=(int **), dereference_type=(void **) is ok;
210+
// - object_type=(int **), dereference_type=(void *) is ok;
211+
// - object_type=(int *), dereference_type=(void **) is not ok;
212+
const typet *object_unwrapped = &object_type;
213+
const typet *dereference_unwrapped = &dereference_type;
214+
while(object_unwrapped->id() == ID_pointer &&
215+
dereference_unwrapped->id() == ID_pointer)
216+
{
217+
object_unwrapped = &object_unwrapped->subtype();
218+
dereference_unwrapped = &dereference_unwrapped->subtype();
219+
}
220+
if(dereference_unwrapped->id() == ID_empty)
221+
{
222+
return true;
223+
}
224+
else if(dereference_unwrapped->id() == ID_pointer &&
225+
object_unwrapped->id() != ID_pointer)
226+
{
227+
#ifdef DEBUG
228+
std::cout << "value_set_dereference: the dereference type has "
229+
"too many ID_pointer levels"
230+
<< std::endl;
231+
std::cout << " object_type: " << object_type.pretty() << std::endl;
232+
std::cout << " dereference_type: " << dereference_type.pretty()
233+
<< std::endl;
234+
#endif
235+
}
206236

207237
if(base_type_eq(object_type, dereference_type, ns))
208238
return true; // ok, they just match

0 commit comments

Comments
 (0)