@@ -201,13 +201,25 @@ 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 (anything can be dereferenced to void type)
206-
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 not ok;
211+ typet object_unwrapped = object_type;
212+ typet dereference_unwrapped = dereference_type;
213+ while (object_unwrapped.id () == ID_pointer &&
214+ dereference_unwrapped.id () == ID_pointer)
215+ {
216+ object_unwrapped = object_unwrapped.subtype ();
217+ dereference_unwrapped = dereference_unwrapped.subtype ();
218+ }
207219 if (
208- object_type .id () == ID_pointer && dereference_type. id () == ID_pointer &&
209- dereference_type. subtype (). id () == ID_empty )
210- return true ; // also ok (any pointer can be dereferenced to a void pointer)
220+ dereference_unwrapped .id () == ID_empty &&
221+ object_unwrapped. id () != ID_pointer )
222+ return true ;
211223
212224 if (base_type_eq (object_type, dereference_type, ns))
213225 return true ; // ok, they just match
0 commit comments