Skip to content

Commit 04e9f6e

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 1ab5de1 commit 04e9f6e

File tree

8 files changed

+71
-55
lines changed

8 files changed

+71
-55
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/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
@@ -357,19 +357,6 @@ bool value_set_dereferencet::dereference_type_compare(
357357
if(object_type == dereference_type)
358358
return true; // ok, they just match
359359

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

src/util/std_types.cpp

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

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

src/util/std_types.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,6 @@ class struct_typet:public struct_union_typet
233233
{
234234
}
235235

236-
bool is_prefix_of(const struct_typet &other) const;
237-
238236
/// A struct may be a class, where members may have access restrictions.
239237
bool is_class() const
240238
{

0 commit comments

Comments
 (0)