Skip to content

Commit 5c95d44

Browse files
committed
Allow void* pointers cast to another pointer type
That's the expr.type() rather than the representation class.
1 parent 8ba10aa commit 5c95d44

10 files changed

+90
-2
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
int main()
3+
{
4+
int *i_was_malloced = malloc(sizeof(int) * 10);
5+
6+
// q[0] = 99;
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
main.c
3+
--variable-sensitivity --vsd-pointers constants --show
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
main::1::i_was_malloced \(\) -> ptr ->\(heap allocation\)
7+
--
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
main.c
3+
--variable-sensitivity --vsd-pointers top-bottom --show
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
main::1::i_was_malloced \(\) -> TOP
7+
--
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
main.c
3+
--variable-sensitivity --vsd-pointers value-set --show
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
main::1::i_was_malloced \(\) -> value-set-begin: ptr ->\(heap allocation\) :value-set-end
7+
--

src/analyses/variable-sensitivity/abstract_pointer_object.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ abstract_object_pointert abstract_pointer_objectt::expression_transform(
4646
if(expr.id() == ID_dereference)
4747
return read_dereference(environment, ns);
4848

49+
if(expr.id() == ID_typecast)
50+
{
51+
const typecast_exprt &tce = to_typecast_expr(expr);
52+
if(tce.op().id() == ID_symbol && is_void_pointer(tce.op().type()))
53+
{
54+
auto obj = environment.eval(tce.op(), ns);
55+
auto pointer = std::dynamic_pointer_cast<const abstract_pointer_objectt>(
56+
obj->unwrap_context());
57+
if(pointer)
58+
return pointer->typecast(tce.type());
59+
}
60+
}
61+
4962
return abstract_objectt::expression_transform(
5063
expr, operands, environment, ns);
5164
}
@@ -87,6 +100,14 @@ abstract_object_pointert abstract_pointer_objectt::write_dereference(
87100
return std::make_shared<abstract_pointer_objectt>(type(), true, false);
88101
}
89102

103+
abstract_object_pointert
104+
abstract_pointer_objectt::typecast(const typet &new_type) const
105+
{
106+
INVARIANT(is_void_pointer(type()), "Only allow pointer casting from void*");
107+
return std::make_shared<abstract_pointer_objectt>(
108+
new_type, is_top(), is_bottom());
109+
}
110+
90111
void abstract_pointer_objectt::get_statistics(
91112
abstract_object_statisticst &statistics,
92113
abstract_object_visitedt &visited,

src/analyses/variable-sensitivity/abstract_pointer_object.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class abstract_pointer_objectt : public abstract_objectt,
9595
const std::stack<exprt> &stack,
9696
const abstract_object_pointert &value,
9797
bool merging_write) const;
98+
99+
virtual abstract_object_pointert typecast(const typet &new_type) const;
98100
};
99101

100102
#endif // CPROVER_ANALYSES_VARIABLE_SENSITIVITY_ABSTRACT_POINTER_OBJECT_H

src/analyses/variable-sensitivity/constant_pointer_abstract_object.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
3333
}
3434

3535
constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
36+
const typet &new_type,
3637
const constant_pointer_abstract_objectt &old)
37-
: abstract_pointer_objectt(old), value_stack(old.value_stack)
38+
: abstract_pointer_objectt(new_type, old.is_top(), old.is_bottom()),
39+
value_stack(old.value_stack)
3840
{
3941
}
4042

@@ -121,6 +123,10 @@ void constant_pointer_abstract_objectt::output(
121123

122124
out << symbol_pointed_to.get_identifier();
123125
}
126+
else if(addressee.id() == ID_dynamic_object)
127+
{
128+
out << "heap allocation";
129+
}
124130
else if(addressee.id() == ID_index)
125131
{
126132
auto const &array_index = to_index_expr(addressee);
@@ -209,6 +215,13 @@ abstract_object_pointert constant_pointer_abstract_objectt::write_dereference(
209215
}
210216
}
211217

218+
abstract_object_pointert
219+
constant_pointer_abstract_objectt::typecast(const typet &new_type) const
220+
{
221+
INVARIANT(is_void_pointer(type()), "Only allow pointer casting from void*");
222+
return std::make_shared<constant_pointer_abstract_objectt>(new_type, *this);
223+
}
224+
212225
void constant_pointer_abstract_objectt::get_statistics(
213226
abstract_object_statisticst &statistics,
214227
abstract_object_visitedt &visited,

src/analyses/variable-sensitivity/constant_pointer_abstract_object.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ class constant_pointer_abstract_objectt : public abstract_pointer_objectt
3434
/// Asserts if both top and bottom are true
3535
constant_pointer_abstract_objectt(const typet &type, bool top, bool bottom);
3636

37-
/// \param old: the abstract object to copy from
3837
constant_pointer_abstract_objectt(
38+
const typet &type,
3939
const constant_pointer_abstract_objectt &old);
4040

4141
/// \param expr: the expression to use as the starting pointer for
@@ -106,6 +106,8 @@ class constant_pointer_abstract_objectt : public abstract_pointer_objectt
106106
const abstract_object_pointert &value,
107107
bool merging_write) const override;
108108

109+
abstract_object_pointert typecast(const typet &new_type) const override;
110+
109111
void get_statistics(
110112
abstract_object_statisticst &statistics,
111113
abstract_object_visitedt &visited,

src/analyses/variable-sensitivity/value_set_pointer_abstract_object.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <analyses/variable-sensitivity/constant_pointer_abstract_object.h>
1313
#include <analyses/variable-sensitivity/context_abstract_object.h>
1414
#include <analyses/variable-sensitivity/value_set_pointer_abstract_object.h>
15+
#include <pointer_expr.h>
1516

1617
#include "abstract_environment.h"
1718

@@ -68,6 +69,14 @@ value_set_pointer_abstract_objectt::value_set_pointer_abstract_objectt(
6869
values.insert(std::make_shared<constant_pointer_abstract_objectt>(type));
6970
}
7071

72+
value_set_pointer_abstract_objectt::value_set_pointer_abstract_objectt(
73+
const typet &new_type,
74+
const value_set_pointer_abstract_objectt &old)
75+
: abstract_pointer_objectt(new_type, old.is_top(), old.is_bottom()),
76+
values(old.values)
77+
{
78+
}
79+
7180
value_set_pointer_abstract_objectt::value_set_pointer_abstract_objectt(
7281
const typet &type,
7382
bool top,
@@ -133,6 +142,13 @@ abstract_object_pointert value_set_pointer_abstract_objectt::write_dereference(
133142
return shared_from_this();
134143
}
135144

145+
abstract_object_pointert
146+
value_set_pointer_abstract_objectt::typecast(const typet &new_type) const
147+
{
148+
INVARIANT(is_void_pointer(type()), "Only allow pointer casting from void*");
149+
return std::make_shared<value_set_pointer_abstract_objectt>(new_type, *this);
150+
}
151+
136152
abstract_object_pointert value_set_pointer_abstract_objectt::resolve_values(
137153
const abstract_object_sett &new_values) const
138154
{

src/analyses/variable-sensitivity/value_set_pointer_abstract_object.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ class value_set_pointer_abstract_objectt : public abstract_pointer_objectt,
2222
/// \copydoc abstract_objectt::abstract_objectt(const typet&)
2323
explicit value_set_pointer_abstract_objectt(const typet &type);
2424

25+
value_set_pointer_abstract_objectt(
26+
const typet &new_type,
27+
const value_set_pointer_abstract_objectt &old);
28+
2529
/// \copydoc abstract_objectt::abstract_objectt(const typet &, bool, bool)
2630
value_set_pointer_abstract_objectt(const typet &type, bool top, bool bottom);
2731

@@ -64,6 +68,8 @@ class value_set_pointer_abstract_objectt : public abstract_pointer_objectt,
6468
const abstract_object_pointert &new_value,
6569
bool merging_write) const override;
6670

71+
abstract_object_pointert typecast(const typet &new_type) const override;
72+
6773
void output(std::ostream &out, const ai_baset &ai, const namespacet &ns)
6874
const override;
6975

0 commit comments

Comments
 (0)