|
8 | 8 | #include <util/simplify_expr_class.h>
|
9 | 9 | #include <util/infix.h>
|
10 | 10 | #include <util/suffix.h>
|
| 11 | +#include <util/c_types.h> |
11 | 12 |
|
12 | 13 | #include <pointer-analysis/dynamic_object_name.h>
|
13 | 14 |
|
@@ -76,6 +77,67 @@ void local_value_sett::get_value_set(
|
76 | 77 | baset::get_value_set(tmp, dest, ns, true);
|
77 | 78 | }
|
78 | 79 |
|
| 80 | +/// Builds a version of expr suitable for alias-comparison |
| 81 | +/// \param expr: The expression to be converted to the alias-uniform structure |
| 82 | +/// \return expr without information which is irrelevant to alias-comparison |
| 83 | +static exprt get_uniform_expr(const exprt &expr) |
| 84 | +{ |
| 85 | + if(const auto desc_ptr=expr_try_dynamic_cast<object_descriptor_exprt>(expr)) |
| 86 | + { |
| 87 | + object_descriptor_exprt ob; |
| 88 | + ob.object() = get_uniform_expr(desc_ptr->object()); |
| 89 | + ob.offset() = desc_ptr->offset(); |
| 90 | + return ob; |
| 91 | + } |
| 92 | + if(can_cast_expr<external_value_set_exprt>(expr)) |
| 93 | + { |
| 94 | + exprt copy = expr; |
| 95 | + copy.set(ID_is_initializer, ID_0); |
| 96 | + return copy; |
| 97 | + } |
| 98 | + return expr; |
| 99 | +} |
| 100 | + |
| 101 | +/// Reconstructs a type of a pointer to the object expr |
| 102 | +/// \param expr: An object in a points-to set we make an alias type for |
| 103 | +/// \return A type of a pointer to the object expr |
| 104 | +static typet get_alias_type(const exprt &expr) |
| 105 | +{ |
| 106 | + if(expr.id()==ID_object_descriptor) |
| 107 | + { |
| 108 | + object_descriptor_exprt ob_expr=to_object_descriptor_expr(expr); |
| 109 | + if(ob_expr.offset().id()==ID_invalid || ob_expr.offset().id()==ID_unknown) |
| 110 | + return pointer_type(ob_expr.object().type()); |
| 111 | + } |
| 112 | + return pointer_type(expr.type()); |
| 113 | +} |
| 114 | + |
| 115 | +void local_value_sett::get_may_alias_set( |
| 116 | + const exprt &expr, |
| 117 | + value_setst::valuest &dest, |
| 118 | + const namespacet &ns) const |
| 119 | +{ |
| 120 | + object_mapt pointed_objects; |
| 121 | + get_value_set(expr, pointed_objects, ns, false); |
| 122 | + std::vector<exprt> uniform_pointed_objects; |
| 123 | + for(const auto &num_obj : pointed_objects.read()) |
| 124 | + uniform_pointed_objects.push_back(get_uniform_expr(to_expr(num_obj))); |
| 125 | + |
| 126 | + for(const auto &name_entry : values) |
| 127 | + for(const auto &enum_eobj : name_entry.second.object_map.read()) |
| 128 | + { |
| 129 | + if(std::find(uniform_pointed_objects.cbegin(), |
| 130 | + uniform_pointed_objects.cend(), |
| 131 | + get_uniform_expr(to_expr(enum_eobj)))!= |
| 132 | + uniform_pointed_objects.cend()) |
| 133 | + { |
| 134 | + dest.push_back(symbol_exprt( |
| 135 | + name_entry.second.identifier, |
| 136 | + get_alias_type(to_expr(enum_eobj)))); |
| 137 | + } |
| 138 | + } |
| 139 | +} |
| 140 | + |
79 | 141 | /// Value-set analysis accrues a `suffix` as it walks down an expression tree--
|
80 | 142 | /// for example, it transforms a `get_value_set_rec(x.y.z)` into
|
81 | 143 | /// `get_value_set_rec(x, suffix = "y.z")`. This function recovers the type
|
|
0 commit comments