Skip to content

Commit 5496378

Browse files
committed
Value set dereferencing: do not treat struct prefixes as equal
Two distinct struct types cannot be cast between, even when one is a prefix of the other. Value set dereferencing taking this approach just resulted in propositional encoding producing a warning about invalid type casts.
1 parent c688efd commit 5496378

File tree

9 files changed

+72
-56
lines changed

9 files changed

+72
-56
lines changed

jbmc/regression/jbmc/simplify-classid-of-interface/test_no_simplify_vccs.desc

Lines changed: 0 additions & 11 deletions
This file was deleted.

regression/cbmc/Pointer21/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
main.c
33
--pointer-check
44
^EXIT=0$

regression/cbmc/struct2/main.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
struct T
2+
{
3+
// intentionally empty to trigger is_prefix_of code (empty structs, however,
4+
// are a GCC-only feature)
5+
};
6+
7+
struct S
8+
{
9+
struct T t;
10+
int other;
11+
};
12+
13+
void foo(struct S s2)
14+
{
15+
struct T *p = &s2.t;
16+
struct T t2 = *p;
17+
__CPROVER_assert(0, "");
18+
}
19+
20+
int main()
21+
{
22+
struct S s;
23+
foo(s);
24+
}

regression/cbmc/struct2/test.desc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE gcc-only broken-smt-backend
2+
main.c
3+
4+
^VERIFICATION FAILED$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
9+
--
10+
This test must not generate a warning about typecasts (between different struct
11+
types) being ignored.

regression/cbmc/struct5/main.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <assert.h>
2+
3+
struct a
4+
{
5+
int x;
6+
};
7+
struct b
8+
{
9+
struct a p;
10+
int y;
11+
};
12+
13+
int f00(struct a *ptr)
14+
{
15+
return ptr->x;
16+
}
17+
18+
int main()
19+
{
20+
struct b z = {{1}, 2};
21+
22+
assert(&z == &(z.p));
23+
assert(&z == &(z.p.x));
24+
25+
assert(f00(&z) == z.p.x);
26+
27+
return 0;
28+
}

regression/cbmc/struct5/test.desc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring

src/pointer-analysis/value_set_dereference.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -358,19 +358,6 @@ bool value_set_dereferencet::dereference_type_compare(
358358
if(object_type == dereference_type)
359359
return true; // ok, they just match
360360

361-
// check for struct prefixes
362-
363-
const typet ot_base=ns.follow(object_type),
364-
dt_base=ns.follow(dereference_type);
365-
366-
if(ot_base.id()==ID_struct &&
367-
dt_base.id()==ID_struct)
368-
{
369-
if(to_struct_type(dt_base).is_prefix_of(
370-
to_struct_type(ot_base)))
371-
return true; // ok, dt is a prefix of ot
372-
}
373-
374361
// we are generous about code pointers
375362
if(dereference_type.id()==ID_code &&
376363
object_type.id()==ID_code)

src/util/std_types.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -104,35 +104,6 @@ optionalt<struct_typet::baset> struct_typet::get_base(const irep_idt &id) const
104104
return {};
105105
}
106106

107-
/// Returns true if the struct is a prefix of \a other, i.e., if this struct
108-
/// has n components then the component types and names of this struct must
109-
/// match the first n components of \a other struct.
110-
/// \param other: Struct type to compare with.
111-
bool struct_typet::is_prefix_of(const struct_typet &other) const
112-
{
113-
const componentst &ot_components=other.components();
114-
const componentst &tt_components=components();
115-
116-
if(ot_components.size()<
117-
tt_components.size())
118-
return false;
119-
120-
componentst::const_iterator
121-
ot_it=ot_components.begin();
122-
123-
for(const auto &tt_c : tt_components)
124-
{
125-
if(ot_it->type() != tt_c.type() || ot_it->get_name() != tt_c.get_name())
126-
{
127-
return false; // they just don't match
128-
}
129-
130-
ot_it++;
131-
}
132-
133-
return true; // ok, *this is a prefix of ot
134-
}
135-
136107
/// Returns true if the type is a reference.
137108
bool is_reference(const typet &type)
138109
{

src/util/std_types.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,6 @@ class struct_typet:public struct_union_typet
239239
{
240240
}
241241

242-
bool is_prefix_of(const struct_typet &other) const;
243-
244242
/// A struct may be a class, where members may have access restrictions.
245243
bool is_class() const
246244
{

0 commit comments

Comments
 (0)