PIPS
constant-path-utils.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "misc.h"
#include "text.h"
#include "text-util.h"
#include "properties.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "points-to.h"
+ Include dependency graph for constant-path-utils.c:

Go to the source code of this file.

Functions

cell make_nowhere_cell ()
 This file contains all the operators defining constant paths : More...
 
cell make_typed_nowhere_cell (type t)
 
cell cell_to_nowhere_sink (cell source)
 assuming source is a reference to a pointer, build the corresponding sink when the pointer is not initialized, i.e. More...
 
set points_to_anywhere_typed (list lhs_list, set input)
 Already exists in points_to_general_algorithm.c, to be removed later... More...
 
set points_to_anywhere (list lhs_list, set input)
 
list array_to_constant_paths (expression e, set in __attribute__((__unused__)))
 input : expression e and a set of points_to output : a set of constant paths translates an expression into a set of constant paths by first changing operators like . More...
 
cell max_module (cell m1, cell m2)
 we define operator max fot the lattice Module which has any_module as top and a bottom which is not yet clearly defined (maybe no_module) max_module : Module * Module -> Module Side effects on m1 if we have an anywhere location to return. More...
 
bool entity_any_module_p (entity e)
 operator kill for the dimension Module: More...
 
bool opkill_may_module (cell m1, cell m2)
 
bool opkill_must_module (cell m1, cell m2)
 
cell op_gen_module (cell m1, __attribute__((__unused__)) cell m2)
 Operator gen for modules: m1 is the sink, m2 the source (m2 points to m1) opkill_gen_module : Module * Module -> Module. More...
 
bool opkill_may_name (cell n1, cell n2)
 We define operators for the lattice Name which can be a: -variable of a the program -malloc -NULL /0 -STATIC/STACK/DYNAMIC/HEAP/FORMAL -nowhere/anywhere. More...
 
bool opkill_must_name (cell n1, cell n2)
 
type max_type (type t1, type t2)
 
bool opkill_may_type (type t1, type t2)
 
bool opkill_must_type (type t1, type t2)
 opkill_must_type is the same as op_kill_may_type... More...
 
type opgen_may_type (type t1, type t2)
 
type opgen_must_type (type t1, type t2)
 the same as opgen_may_type More...
 
bool opkill_may_reference (cell c1, cell c2)
 
bool opkill_must_reference (cell c1, cell c2)
 
bool opkill_may_vreference (cell c1, cell c2)
 FI: really weird and unefficient. More...
 
bool opkill_must_vreference (cell c1, cell c2)
 returns true if c2 must kills c1 because of the subscript expressions More...
 
bool opkill_may_constant_path (cell c1, cell c2)
 
bool opkill_must_constant_path (cell c1, cell c2)
 returns true if c2 kills c1 More...
 
set kill_may_set (list L, set in_may)
 Compute the set of arcs in the input points-to relation "in" whose approximation must be changed from "exact" to "may". More...
 
set kill_must_set (list L, set in)
 Generate the subset of arcs that must be removed from the points-to graph "in". More...
 
set points_to_may_filter (set in)
 returns a set which contains all the MAY points to More...
 
set points_to_must_filter (set in)
 returns a set which contains all the EXACT points to More...
 
bool address_of_expression_p (expression e)
 shoud be moved to expression.c More...
 
bool subscript_expression_p (expression e)
 
set gen_may_set (list L, list R, set in_may, bool *address_of_p)
 Should be moved to anywhere_abstract_locations.c. More...
 
set gen_must_set (list L, list R, set in_must, bool *address_of_p)
 
bool unique_location_cell_p (cell c)
 Does cell "c" represent a unique memory location or a set of memory locations? More...
 
set gen_may_constant_paths (cell l, list R, set in_may, bool *address_of_p, int Lc)
 
set gen_must_constant_paths (cell l, list R, set in_must, bool *address_of_p, int Lc)
 Build a set of arcs from cell l towards cells in list R if *address_p is true, or towards cells pointed by cells in list R if not. More...
 
points_to opgen_may_constant_path (cell l __attribute__((__unused__)), cell r __attribute__((__unused__)))
 
points_to opgen_must_constant_path (cell l __attribute__((__unused__)), cell r __attribute__((__unused__)))
 
bool opgen_may_module (entity e1, entity e2)
 
bool opgen_must_module (entity e1, entity e2)
 
bool opgen_may_name (entity e1, entity e2)
 
bool opgen_must_name (entity e1, entity e2)
 
bool opgen_may_vreference (list vr1, list vr2)
 
bool atomic_constant_path_p (cell cp)
 Could be replaced by abstract_location_p() but this later don't take into account the null location. More...
 
set opgen_null_location (set L, cell r)
 
set points_to_independent_store (set s)
 
bool equal_must_vreference (cell c1, cell c2)
 
set points_to_nowhere (list lhs_list, set input)
 arg1: list of cells arg2: set of points-to Create a points-to set with elements of lhs_list as source and NOWHERE as sink. More...
 

Function Documentation

◆ address_of_expression_p()

bool address_of_expression_p ( expression  e)

shoud be moved to expression.c

Definition at line 741 of file constant-path-utils.c.

742 {
743  bool address_of_p = false;
744  syntax s = expression_syntax(e);
745  if (syntax_call_p(s)) {
746  if (entity_an_operator_p(call_function(syntax_call(s)), ADDRESS_OF))
747  address_of_p = true;
748  }
749  return address_of_p;
750 }
#define entity_an_operator_p(e, name)
macros
#define call_function(x)
Definition: ri.h:709
#define syntax_call_p(x)
Definition: ri.h:2734
#define syntax_call(x)
Definition: ri.h:2736
#define expression_syntax(x)
Definition: ri.h:1247

References call_function, entity_an_operator_p, expression_syntax, syntax_call, and syntax_call_p.

◆ array_to_constant_paths()

list array_to_constant_paths ( expression  e,
set in   __attribute__(__unused__) 
)

input : expression e and a set of points_to output : a set of constant paths translates an expression into a set of constant paths by first changing operators like .

and -> into p[0](get_memory_path()). Then evaluate this path by using points_toÚrelations already computed (eval_cell_with_points_to()). Finaly construct a set of constant paths according to the list returned by eval_cell_with_points_to().

Definition at line 176 of file constant-path-utils.c.

177 {
178  list l = NIL;
179  bool changed = false;
180  //effect ef = effect_undefined;
181  //reference r = reference_undefined;
182  cell c = cell_undefined;
183  cell c_new = cell_undefined;
184  //int i;
187  if(array_reference_p(er)) {
188  c = make_cell_reference(er);
189  c_new = simple_cell_to_store_independent_cell(c, &changed);
190  }
191  else {
192  c_new = make_cell_reference(er);
193  }
195  l = CONS(CELL, c_new, NIL);
196 
197  return l;
198 }
cell make_cell_reference(reference _field_)
Definition: effects.c:293
void generic_effects_reset_all_methods(void)
void set_methods_for_proper_simple_effects(void)
cell simple_cell_to_store_independent_cell(cell, bool *)
#define cell_undefined
Definition: effects.h:430
#define CELL(x)
CELL.
Definition: effects.h:424
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
bool array_reference_p(reference r)
predicates on references
Definition: expression.c:1861
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References array_reference_p(), CELL, cell_undefined, CONS, expression_reference(), generic_effects_reset_all_methods(), make_cell_reference(), NIL, set_methods_for_proper_simple_effects(), and simple_cell_to_store_independent_cell().

+ Here is the call graph for this function:

◆ atomic_constant_path_p()

bool atomic_constant_path_p ( cell  cp)

Could be replaced by abstract_location_p() but this later don't take into account the null location.

Parameters
cpp

Definition at line 1243 of file constant-path-utils.c.

1244 {
1245  bool atomic_cp_p = true;
1247  entity e = reference_variable(r);
1248 
1250  atomic_cp_p = false;
1251  return atomic_cp_p;
1252 }
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
bool entity_abstract_location_p(entity al)
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
#define reference_variable(x)
Definition: ri.h:2326
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87

References cell_any_reference(), cp, entity_abstract_location_p(), entity_null_locations_p(), and reference_variable.

+ Here is the call graph for this function:

◆ cell_to_nowhere_sink()

cell cell_to_nowhere_sink ( cell  source)

assuming source is a reference to a pointer, build the corresponding sink when the pointer is not initialized, i.e.

is undefined.

Parameters
sourceource

Definition at line 55 of file constant-path-utils.c.

56 {
57  bool type_sensitive_p = !get_bool_property("ALIASING_ACROSS_TYPES");
58  cell sink = cell_undefined;
59  if(type_sensitive_p) {
60  // FI: let's hope we create neither sharing nor memory leak
61  bool to_be_freed_p = true;
62  type t = type_to_pointed_type(cell_to_type(source, &to_be_freed_p));
64  if(to_be_freed_p) free_type(t);
65  }
66  else
67  sink = make_nowhere_cell();
68  return sink;
69 }
type copy_type(type p)
TYPE.
Definition: ri.c:2655
void free_type(type p)
Definition: ri.c:2658
cell make_nowhere_cell()
This file contains all the operators defining constant paths :
cell make_typed_nowhere_cell(type t)
type cell_to_type(cell, bool *)
Definition: type.c:513
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
type type_to_pointed_type(type)
returns t if t is not a pointer type, and the pointed type if t is a pointer type.
Definition: type.c:5265

References cell_to_type(), cell_undefined, copy_type(), free_type(), get_bool_property(), make_nowhere_cell(), make_typed_nowhere_cell(), and type_to_pointed_type().

Referenced by declaration_statement_to_points_to(), malloc_to_points_to_sinks(), and user_call_to_points_to_fast_interprocedural().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ entity_any_module_p()

bool entity_any_module_p ( entity  e)

operator kill for the dimension Module:

  • modules should be different from any_module otherwise we return false
  • when modules are different from any_module we test the equality of their names opkill_may_module : Module * Module -> Bool opkill_must_module : Module * Module -> Bool test if a module is the any_module location, to be moved to anywhere_abstract_locations.c later...

Definition at line 234 of file constant-path-utils.c.

235 {
236  bool any_module_p;
238 
239  return any_module_p;
240 }
#define ANY_MODULE_NAME
#define same_string_p(s1, s2)
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092

References ANY_MODULE_NAME, entity_module_name(), and same_string_p.

Referenced by opgen_may_module(), opgen_must_module(), opkill_may_module(), and opkill_must_module().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ equal_must_vreference()

bool equal_must_vreference ( cell  c1,
cell  c2 
)
Parameters
c11
c22

Definition at line 1292 of file constant-path-utils.c.

1293 {
1294  int i = 0;
1295  bool changed = false;
1297  c1 = simple_cell_to_store_independent_cell(c1, &changed);
1298  c2 = simple_cell_to_store_independent_cell(c2, &changed);
1300  reference r1 = cell_any_reference(c1);
1301  reference r2 = cell_any_reference(c2);
1302  entity v1 = reference_variable(r1);
1303  entity v2 = reference_variable(r2);
1304  list sl1 = NIL, sl2 = NIL;
1305  // FI: memory leak? generation of a new string?
1306  extern const char* entity_minimal_user_name(entity);
1307 
1309  if (i==0) {
1310  sl1 = reference_indices(r1);
1311  sl2 = reference_indices(r2);
1312  if( (int)gen_length(sl1) == (int)gen_length(sl2) ) {
1313  for (;i==0 && !ENDP(sl1) && ! ENDP(sl2) ; POP(sl1), POP(sl2)){
1314  expression se1 = EXPRESSION(CAR(sl1));
1315  expression se2 = EXPRESSION(CAR(sl2));
1316  if( unbounded_expression_p(se1) ){
1317  i = 0;
1318  }
1319  else if (expression_constant_p(se1) && expression_constant_p(se2)){
1320  int i1 = expression_to_int(se1);
1321  int i2 = expression_to_int(se2);
1322  i = i2>i1? 1 : (i2<i1? -1 : 0);
1323  if (i==0){
1324  // FI: why not use expression_equal_p()? + memory leak
1325  string s1 = expression_to_string(se1);
1326  string s2 = expression_to_string(se2);
1327  i = strcmp(s1, s2);
1328  }
1329  }
1330  else {
1331  string s1 = expression_to_string(se1);
1332  string s2 = expression_to_string(se2);
1333  i = strcmp(s1, s2);
1334  }
1335  }
1336  }
1337  else
1338  i = 1;
1339  }
1340 
1341  return (i==0? true: false);
1342 }
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
size_t gen_length(const list l)
Definition: list.c:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
const char * entity_minimal_user_name(entity e)
Do not preserve scope information.
Definition: naming.c:223
string expression_to_string(expression e)
Definition: expression.c:77
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
s1
Definition: set.c:247

References CAR, cell_any_reference(), ENDP, entity_minimal_user_name(), EXPRESSION, expression_constant_p(), expression_to_int(), expression_to_string(), gen_length(), generic_effects_reset_all_methods(), NIL, POP, reference_indices, reference_variable, s1, set_methods_for_proper_simple_effects(), simple_cell_to_store_independent_cell(), and unbounded_expression_p().

Referenced by gen_may_constant_paths(), and gen_must_constant_paths().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ gen_may_constant_paths()

set gen_may_constant_paths ( cell  l,
list  R,
set  in_may,
bool address_of_p,
int  Lc 
)

here we have x = y, then we generate (x,y1,a)|(y,y1,a) as points to relation

locations_equal_p

&& !entity_abstract_location_p(el)

Should be replaced by opgen_constant_path(l,r)

if(reference_unbounded_indices_p(ref))

a = make_approximation_may();

Make sure the types are compatible...

Parameters
in_mayn_may
address_of_pddress_of_p
Lcc

Definition at line 1003 of file constant-path-utils.c.

1008 {
1010  points_to_rank);
1012  if(!(*address_of_p)){
1013  pips_internal_error("address_of_p should always be true in the new implementation/.\n");
1014  /* here we have x = y, then we generate (x,y1,a)|(y,y1,a) as
1015  points to relation */
1016  FOREACH(cell, r, R){
1017  SET_FOREACH(points_to, i, in_may){
1018  if (/* locations_equal_p */equal_must_vreference(r, points_to_source(i)) /* && !entity_abstract_location_p(el) */ ){
1019  cell nl = copy_cell(l);
1020  pt = make_points_to(nl,
1024  }
1027  bool t_to_be_freed = false;
1028  type t = points_to_reference_to_type(ref, &t_to_be_freed);
1029  if(pointer_type_p(t)) {
1030  cell nl = copy_cell(l);
1032  }
1033  else {
1034  cell nl = copy_cell(l);
1036  }
1037  if (t_to_be_freed) free_type(t);
1038  }
1039  if(!points_to_undefined_p(pt)) {
1040  set_add_element(gen_may_cps, gen_may_cps, (void*) pt);
1041  }
1042  }
1043  }
1044  }
1045  else {
1046  int Rc = (int) gen_length(R);
1047  FOREACH(cell, r, R){
1048  // FI: check the unicity of the locations
1049  // FI: relationship with atomic_points_to_cell_p()?
1050  approximation a = (Lc+Rc>2
1051  || !unique_location_cell_p(l)
1052  || !unique_location_cell_p(r)) ?
1054  /* Should be replaced by opgen_constant_path(l,r) */
1055  //reference ref = cell_any_reference(r);
1056  /* if(reference_unbounded_indices_p(ref)) */
1057  /* a = make_approximation_may(); */
1058  cell nl = copy_cell(l);
1059  /* Make sure the types are compatible... */
1061  pt = make_points_to(nl, copy_cell(r), a, make_descriptor_none());
1062  set_add_element(gen_may_cps, gen_may_cps, (void*)pt);
1063  }
1064  }
1065 
1066  return gen_may_cps;
1067 }
approximation make_approximation_exact(void)
Definition: effects.c:185
approximation make_approximation_may(void)
Definition: effects.c:179
descriptor make_descriptor_none(void)
Definition: effects.c:442
cell copy_cell(cell p)
CELL.
Definition: effects.c:246
points_to make_points_to(cell a1, cell a2, approximation a3, descriptor a4)
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
void const char const char const int
bool unique_location_cell_p(cell c)
Does cell "c" represent a unique memory location or a set of memory locations?
bool equal_must_vreference(cell c1, cell c2)
type points_to_reference_to_type(reference, bool *)
FI: I need more generality than is offered by cell_to_type()
Definition: type.c:527
void points_to_cell_types_compatibility(cell, cell)
Make sure that cell l can points towards cell r.
Definition: type.c:985
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define pips_internal_error
Definition: misc-local.h:149
set set_generic_make(set_type, hash_equals_t, hash_rank_t)
what about this replacement? #define SET_MAP(the_item, the_code, the_set) \ { SET_FOREACH(void *,...
Definition: set.c:83
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
@ set_private
Definition: newgen_set.h:45
set set_add_element(set, const set, const void *)
Definition: set.c:152
_uint points_to_rank(const void *, size_t)
create a key which is a concatenation of the source's name, the sink's name and the approximation of ...
int points_to_equal_p(const void *, const void *)
returns true if two points-to arcs "vpt1" and "vpt2" are equal.
Definition: points_to_set.c:98
#define points_to_undefined_p(x)
#define points_to_undefined
#define points_to_sink(x)
#define points_to_source(x)
bool array_entity_p(entity e)
Definition: entity.c:793
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References array_entity_p(), cell_any_reference(), copy_cell(), equal_must_vreference(), FOREACH, free_type(), gen_length(), int, make_approximation_exact(), make_approximation_may(), make_descriptor_none(), make_points_to(), pips_internal_error, pointer_type_p(), points_to_cell_types_compatibility(), points_to_equal_p(), points_to_rank(), points_to_reference_to_type(), points_to_sink, points_to_source, points_to_undefined, points_to_undefined_p, ref, reference_variable, set_add_element(), SET_FOREACH, set_generic_make(), set_private, and unique_location_cell_p().

Referenced by gen_may_set().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ gen_may_set()

set gen_may_set ( list  L,
list  R,
set  in_may,
bool address_of_p 
)

Should be moved to anywhere_abstract_locations.c.

‍**If the source is not precisely known *‍/

It is easier not to have to maintain the consistency between gen_may1 and kill_may.

Parameters
in_mayn_may
address_of_pddress_of_p

Definition at line 813 of file constant-path-utils.c.

814 {
821  int len = (int) gen_length(L);
822 
823  //if(len > 1) {
824  ///* If the source is not precisely known */
825  /* It is easier not to have to maintain the consistency between
826  gen_may1 and kill_may. */
827  if(false) {
828  FOREACH(cell, l, L) {
829  SET_FOREACH(points_to, pt, in_may){
831  //if(!atomic_points_to_cell_p(points_to_source(pt))) {
832  //if(points_to_compare_cell(points_to_source(pt),l)) {
834  // FI: it would be much easier/efficient to modify the approximation of pt
835  // But it is incompatible with the implementation of sets...
840  set_add_element(gen_may1, gen_may1, (void*)npt);
841  //set_del_element(gen_may1, gen_may1, (void*)pt);
842  }
843  // }
844  }
845  }
846  }
847  }
848 
849  // Possibly generate an error for dereferencing an undefined pointer
850  bool error_p =
851  !get_bool_property("POINTS_TO_UNINITIALIZED_POINTER_DEREFERENCING");
852  int lc = (int) gen_length(L);
853  FOREACH(cell, l, L){
855  entity lv = reference_variable(lr);
856  bool null_p = entity_null_locations_p(lv);
857  bool nowhere_p = entity_typed_nowhere_locations_p(lv)
859  string bug = null_p? "a null" : "";
860  bug = nowhere_p? "an undefined" : "";
861  // Can the lhs be accessed?
862  if(null_p || nowhere_p) {
863  // No: two options; either a user_error() for dereferencing an
864  // unitialized pointer or a conversion to anywhere, typed or not
865  // FI: why be tolerant of NULL pointer dereferencing? For may information
866  if(lc==1) {
867  if(error_p)
868  pips_user_error("Dereferencing of %s pointer.\n", bug);
869  else {
870  pips_user_warning("Dereferencing of %s pointer.\n", bug);
871  }
872  }
873  else {
874  pips_user_warning("Possible dereferencing of %s pointer.\n", bug);
875  }
876  type t = entity_type(lv);
878  set gen_l = gen_may_constant_paths(nl, R, in_may, address_of_p, len);
879  set_union(gen_may2, gen_may2, gen_l);
880  }
881  else {
882  // FI: memory leak due to call to call to gen_may_constant_paths()
883  set gen_l = gen_may_constant_paths(l, R, in_may, address_of_p, len);
884  // FI: be careful, the union does not preserve consistency because
885  // the same arc may appear with different approximations
886  set_union(gen_may2, gen_may2, gen_l);
887  // free_set(gen_l);
888  }
889  }
890 
891  set_union(gen_may2, gen_may2, gen_may1);
892  set_union(gen_may2, gen_may2, gen_may3);
893 
894  return gen_may2;
895 }
bool entity_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool entity_typed_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
set gen_may_constant_paths(cell l, list R, set in_may, bool *address_of_p, int Lc)
cell make_anywhere_points_to_cell(type)
Function storing points to information attached to a statement.
Definition: points_to.c:87
#define approximation_exact_p(x)
Definition: effects.h:369
bool cells_may_conflict_p(cell c1, cell c2)
Check if two cell may conflict.
Definition: conflicts.c:696
#define pips_user_warning
Definition: misc-local.h:146
#define pips_user_error
Definition: misc-local.h:147
set set_union(set, const set, const set)
Definition: set.c:211
#define points_to_approximation(x)
#define entity_type(x)
Definition: ri.h:2792
Definition: pip__tab.h:30

References approximation_exact_p, cell_any_reference(), cells_may_conflict_p(), copy_cell(), entity_nowhere_locations_p(), entity_null_locations_p(), entity_type, entity_typed_nowhere_locations_p(), FOREACH, gen_length(), gen_may_constant_paths(), get_bool_property(), int, make_anywhere_points_to_cell(), make_approximation_may(), make_descriptor_none(), make_points_to(), pips_user_error, pips_user_warning, points_to_approximation, points_to_equal_p(), points_to_rank(), points_to_sink, points_to_source, reference_variable, set_add_element(), SET_FOREACH, set_generic_make(), set_private, and set_union().

Referenced by list_assignment_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ gen_must_constant_paths()

set gen_must_constant_paths ( cell  l,
list  R,
set  in_must,
bool address_of_p,
int  Lc 
)

Build a set of arcs from cell l towards cells in list R if *address_p is true, or towards cells pointed by cells in list R if not.

Approximation is must if Lc==1. Lc is the cardinal of L, a set containing l.

FI->AM: I do not understand why the cardinal of R is not used too when deciding if the approximation is may or must. I decide to change the semantics of this function although it is used by the initial analysis.

FI: since *address_of_p is not modified, I do not understand why a pointer is passed.

FI->AM: sharing of a... A new approximation must be generated for each new arc

if we have x = &y then we generate (x,y,a) as points to relation

Should be replaced by opgen_constant_path(l,r)

if(reference_unbounded_indices_p(ref))

a = make_approximation_may();

here we have x = y, then we generate (x,y1,a)|(y,y1,a) as points to relation

locations_equal_p

&& !entity_abstract_location_p(el)

if(array_entity_p(reference_variable(cell_any_reference(r)))){

reference ref = cell_any_reference(r);

expression ex = reference_to_expression(ref);

if(!expression_pointer_p(ex))

pt = make_points_to(l, r, a, make_descriptor_none());

else

pt = make_points_to(l, points_to_sink(i), a, make_descriptor_none());

}

if(!points_to_undefined_p(pt))

set_add_element(gen_must_cps, gen_must_cps, (void*) pt);

if(reference_unbounded_indices_p(ref))

a = make_approximation_may();

Parameters
in_mustn_must
address_of_pddress_of_p
Lcc

Definition at line 1088 of file constant-path-utils.c.

1093 {
1095  points_to_rank);
1097  //approximation a = approximation_undefined;
1098  bool changed = false;
1099  int Rc = (int) gen_length(R);
1100 
1101  // Rc = 0;
1102  if(*address_of_p){
1103  /* if we have x = &y then we generate (x,y,a) as points to relation*/
1104  FOREACH(cell, r, R){
1105  /* Should be replaced by opgen_constant_path(l,r) */
1106  //reference ref = cell_any_reference(r);
1107  /* if(reference_unbounded_indices_p(ref)) */
1108  /* a = make_approximation_may(); */
1109  approximation a = (Lc+Rc>2
1110  || !unique_location_cell_p(l)
1111  || !unique_location_cell_p(r))?
1113  pt = make_points_to(l, r, a, make_descriptor_none());
1114  set_add_element(gen_must_cps, gen_must_cps, (void*)pt);
1115  }
1116  }
1117  else {
1118  /* here we have x = y, then we generate (x,y1,a)|(y,y1,a) as
1119  points to relation */
1120  FOREACH(cell, r, R){
1121  SET_FOREACH(points_to, i, in_must) {
1122  if (/* locations_equal_p */equal_must_vreference(r, points_to_source(i))/* && !entity_abstract_location_p(el) */){
1124  l = simple_cell_to_store_independent_cell(l, &changed);
1126  approximation a = (Lc+Rc>2)?
1129 
1130 
1131  /* if(array_entity_p(reference_variable(cell_any_reference(r)))){ */
1132  /* reference ref = cell_any_reference(r); */
1133  /* expression ex = reference_to_expression(ref); */
1134 
1135  /* if(!expression_pointer_p(ex)) */
1136  /* pt = make_points_to(l, r, a, make_descriptor_none()); */
1137  /* else */
1138  /* pt = make_points_to(l, points_to_sink(i), a, make_descriptor_none()); */
1139  /* } */
1140 
1141  /* if(!points_to_undefined_p(pt)) */
1142  /* set_add_element(gen_must_cps, gen_must_cps, (void*) pt); */
1143 
1146  bool t_to_be_freed = false;
1147  type t = points_to_reference_to_type(ref, &t_to_be_freed);
1148  /* if(reference_unbounded_indices_p(ref)) */
1149  /* a = make_approximation_may(); */
1150  if(!pointer_type_p(t))
1151  pt = make_points_to(l, r, a, make_descriptor_none());
1152  else
1154 
1155  if (t_to_be_freed) free_type(t);
1156  }
1157  if(!points_to_undefined_p(pt))
1158  set_add_element(gen_must_cps, gen_must_cps, (void*) pt);
1159  }
1160  }
1161  }
1162  }
1163 
1164  return gen_must_cps;
1165 }

References array_entity_p(), cell_any_reference(), equal_must_vreference(), FOREACH, free_type(), gen_length(), generic_effects_reset_all_methods(), int, make_approximation_exact(), make_approximation_may(), make_descriptor_none(), make_points_to(), pointer_type_p(), points_to_equal_p(), points_to_rank(), points_to_reference_to_type(), points_to_sink, points_to_source, points_to_undefined, points_to_undefined_p, ref, reference_variable, set_add_element(), SET_FOREACH, set_generic_make(), set_methods_for_proper_simple_effects(), set_private, simple_cell_to_store_independent_cell(), and unique_location_cell_p().

Referenced by gen_must_set().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ gen_must_set()

set gen_must_set ( list  L,
list  R,
set  in_must,
bool address_of_p 
)

if len > 1 we must iterate over in_must and change all points-to relations having L as lhs into may relations

Parameters
in_mustn_must
address_of_pddress_of_p

Definition at line 908 of file constant-path-utils.c.

909 {
914  int len = (int) gen_length(L);
915 
916  /* if len > 1 we must iterate over in_must and change all points-to
917  relations having L as lhs into may relations */
918  if(len > 1){
919  FOREACH(cell, l, L){
920  SET_FOREACH(points_to, pt, in_must){
925  set_add_element(gen_must1, gen_must1, (void*)npt);
926  }
927  }
928  }
929  }
930 
931  bool error_p = false; // generate an error for dereferencing an undefined pointer
932  int lc = (int) gen_length(L);
933  FOREACH(cell, l, L){
934  // Can the lhs be accessed?
936  entity lv = reference_variable(lr);
937  bool null_p = entity_null_locations_p(lv);
938  bool nowhere_p = entity_typed_nowhere_locations_p(lv)
940  string bug = null_p? "a null" : "";
941  bug = nowhere_p? "an undefined" : "";
942  if(null_p || nowhere_p) {
943  // No: two options; either a user_error() for dereferencing an
944  // unitialized pointer or a conversion to anywhere, typed or not
945  if(lc==1) {
946  if(error_p)
947  pips_user_error("Dereferencing of %s pointer.\n", bug);
948  else {
949  pips_user_warning("Dereferencing of %s pointer.\n", bug);
950  }
951  }
952  else {
953  pips_user_warning("Possible dereferencing of %s pointer.\n", bug);
954  }
955  type t = entity_type(lv);
957  set must_l = gen_must_constant_paths(nl, R, in_must, address_of_p, len);
958  set_union(gen_must2, gen_must2, must_l);
959  }
960  else {
961  set must_l = gen_must_constant_paths(l, R, in_must, address_of_p, len);
962  set_union(gen_must2, gen_must2, must_l);
963  // FI: shouldn't must_l be freed?
964  }
965  }
966  set_union(gen_must2, gen_must2,gen_must1);
967 
968  return gen_must2;
969 }
set gen_must_constant_paths(cell l, list R, set in_must, bool *address_of_p, int Lc)
Build a set of arcs from cell l towards cells in list R if *address_p is true, or towards cells point...
bool points_to_compare_cell(cell, cell)

References cell_any_reference(), entity_nowhere_locations_p(), entity_null_locations_p(), entity_type, entity_typed_nowhere_locations_p(), FOREACH, gen_length(), gen_must_constant_paths(), int, make_anywhere_points_to_cell(), make_approximation_may(), make_descriptor_none(), make_points_to(), pips_user_error, pips_user_warning, points_to_compare_cell(), points_to_equal_p(), points_to_rank(), points_to_sink, points_to_source, reference_variable, set_add_element(), SET_FOREACH, set_generic_make(), set_private, and set_union().

+ Here is the call graph for this function:

◆ kill_may_set()

set kill_may_set ( list  L,
set  in_may 
)

Compute the set of arcs in the input points-to relation "in" whose approximation must be changed from "exact" to "may".

This set is linked to set "gen_may1", although consistency would be easier to maintain if only "kill_may" were used to generate the new arcs...

kill_may = { pt in "in"| exact(pt) ^ \exists l in L conflict(l, source(pt))}

The restriction to !atomic does not seem useful.

Parameters
in_mayn_may

Definition at line 668 of file constant-path-utils.c.

669 {
672  FOREACH(cell, l, L) {
673  SET_FOREACH(points_to, pt, in_may) {
674  cell pt_source = points_to_source(pt);
675  if (opkill_may_constant_path(pt_source,l)) {
676  points_to npt = make_points_to(pt_source,
677  points_to_sink(pt),
680  set_add_element(kill_may, kill_may, (void*)npt);
681  }
682  }
683  }
684  return kill_may;
685 }
bool opkill_may_constant_path(cell c1, cell c2)

References FOREACH, make_approximation_exact(), make_descriptor_none(), make_points_to(), opkill_may_constant_path(), points_to_equal_p(), points_to_rank(), points_to_sink, points_to_source, set_add_element(), SET_FOREACH, set_generic_make(), and set_private.

Referenced by list_assignment_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ kill_must_set()

set kill_must_set ( list  L,
set  in 
)

Generate the subset of arcs that must be removed from the points-to graph "in".

Set "in_must" is the subset of set "in" with exact points-to arcs only.

kill_1 = kill_must = {pt in "in" | source(pt) in L ^ |L|=1 ^ atomic(L) }

where "atomic(L)" is a short cut for "atomic(l) forall l in L"

Here, correctly, the atomicity is not checked directly, but properly, using an operator of the lattice.

Parameters
inn

Definition at line 700 of file constant-path-utils.c.

701 {
702  set kill_must = new_simple_pt_map();
703  int nL = (int) gen_length(L);
704 
705  if(nL==1) {
706  cell l = CELL(CAR(L));
707  SET_FOREACH(points_to, s, in) {
709  set_add_element(kill_must, kill_must,(void*)s);
710  }
711  }
712  return kill_must;
713 }
#define new_simple_pt_map()
bool opkill_must_constant_path(cell c1, cell c2)
returns true if c2 kills c1

References CAR, CELL, gen_length(), int, new_simple_pt_map, opkill_must_constant_path(), points_to_source, set_add_element(), and SET_FOREACH.

Referenced by list_assignment_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_nowhere_cell()

cell make_nowhere_cell ( void  )

This file contains all the operators defining constant paths :

constant-path-utils.c

CP = Mdodule * Name * Type *Vref. To calculate the lattice PC operators we define these operators first on each of its dimensions. Each dimension represents a lattice with a bottom and a top.

Definition at line 35 of file constant-path-utils.c.

36 {
39  cell sink = make_cell_reference(r);
40  return sink;
41 }
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
entity entity_all_xxx_locations(string xxx)
return ANY_MODULE:xxx
#define NOWHERE_LOCATION

References entity_all_xxx_locations(), make_cell_reference(), make_reference(), NIL, and NOWHERE_LOCATION.

Referenced by cell_to_nowhere_sink(), intrinsic_call_to_points_to(), points_to_nowhere(), remove_points_to_cell(), and unary_intrinsic_call_to_points_to_sinks().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_typed_nowhere_cell()

cell make_typed_nowhere_cell ( type  t)

Definition at line 43 of file constant-path-utils.c.

44 {
47  cell sink = make_cell_reference(r);
48  return sink;
49 }
entity entity_all_xxx_locations_typed(string xxx, type t)
FI->AM: the predicate entity_all_xxx_locations_typed_p() is missing...

References entity_all_xxx_locations_typed(), make_cell_reference(), make_reference(), NIL, and NOWHERE_LOCATION.

Referenced by cell_to_nowhere_sink(), freed_list_to_points_to(), points_to_set_block_projection(), and remove_points_to_cell().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ max_module()

cell max_module ( cell  m1,
cell  m2 
)

we define operator max fot the lattice Module which has any_module as top and a bottom which is not yet clearly defined (maybe no_module) max_module : Module * Module -> Module Side effects on m1 if we have an anywhere location to return.

Parameters
m11
m22

Definition at line 207 of file constant-path-utils.c.

208 {
209  reference r1 = cell_any_reference(m1);
210  reference r2 = cell_any_reference(m2);
211  entity e1 = reference_variable(r1);
212  entity e2 = reference_variable(r2);
213 
215  return m1;
216  else {
217  e1 = entity_all_locations();
218  r1 = make_reference(e1,NIL);
219  m1 = make_cell_reference(r1);
220  }
221  return m1;
222 }
entity entity_all_locations()
eturn ANY_MODULE:ANYWHERE (the top of the lattice)
#define entity_name(x)
Definition: ri.h:2790

References cell_any_reference(), entity_all_locations(), entity_name, make_cell_reference(), make_reference(), NIL, reference_variable, and same_string_p.

+ Here is the call graph for this function:

◆ max_type()

type max_type ( type  t1,
type  t2 
)
Parameters
t11
t22

Definition at line 411 of file constant-path-utils.c.

412 {
413  if (!type_unknown_p(t1) && ! type_unknown_p(t2) && type_equal_p(t1,t2))
414  return t1;
415  else {
416  type t = MakeTypeUnknown();
417  return t;
418  }
419 }
type MakeTypeUnknown(void)
Definition: type.c:97
bool type_equal_p(type, type)
Definition: type.c:547
#define type_unknown_p(x)
Definition: ri.h:2956

References MakeTypeUnknown(), type_equal_p(), and type_unknown_p.

+ Here is the call graph for this function:

◆ op_gen_module()

cell op_gen_module ( cell  m1,
__attribute__((__unused__)) cell  m2 
)

Operator gen for modules: m1 is the sink, m2 the source (m2 points to m1) opkill_gen_module : Module * Module -> Module.

we return the module m1 whatever is its type (#any_module, TOP-LEVEL, any_module)

Definition at line 282 of file constant-path-utils.c.

283 {
284  /* we return the module m1 whatever is its type (#any_module,
285  TOP-LEVEL, any_module) */
286  return m1;
287 
288 }

◆ opgen_may_constant_path()

points_to opgen_may_constant_path ( cell l   __attribute__(__unused__),
cell r   __attribute__(__unused__) 
)

Definition at line 1167 of file constant-path-utils.c.

1168 {
1170  return pt;
1171 }

References points_to_undefined.

◆ opgen_may_module()

bool opgen_may_module ( entity  e1,
entity  e2 
)
Parameters
e11
e22

Definition at line 1179 of file constant-path-utils.c.

1180 {
1181  const char* m1 = entity_module_name(e1);
1182  const char* m2 = entity_module_name(e2);
1183 
1185  return true;
1186  else
1187  return same_string_p(m1, m2);
1188 }
bool entity_any_module_p(entity e)
operator kill for the dimension Module:

References entity_any_module_p(), entity_module_name(), and same_string_p.

+ Here is the call graph for this function:

◆ opgen_may_name()

bool opgen_may_name ( entity  e1,
entity  e2 
)
Parameters
e11
e22

Definition at line 1201 of file constant-path-utils.c.

1202 {
1203  string n1 = entity_name(e1);
1204  string n2 = entity_name(e2);
1205 
1207  return true;
1208  else
1209  return same_string_p(n1, n2);
1210 }

References entity_abstract_location_p(), entity_name, and same_string_p.

+ Here is the call graph for this function:

◆ opgen_may_type()

type opgen_may_type ( type  t1,
type  t2 
)
Parameters
t11
t22

Definition at line 437 of file constant-path-utils.c.

438 {
439  if (!type_unknown_p(t1)&& ! type_unknown_p(t2))
440  return t1;
441  else {
442  type t = MakeTypeUnknown();
443  return t;
444  }
445 }

References MakeTypeUnknown(), and type_unknown_p.

Referenced by opgen_must_type().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ opgen_may_vreference()

bool opgen_may_vreference ( list  vr1,
list  vr2 
)
Parameters
vr1r1
vr2r2

Definition at line 1223 of file constant-path-utils.c.

1224 {
1225  bool gen_may_p = true;
1226 
1227  if(ENDP(vr1) || ENDP(vr2))
1228  return gen_may_p;
1229  else{
1230  FOREACH(expression, e, vr1){
1232  gen_may_p = false;
1233  break;
1234  }
1235  }
1236  }
1237 
1238  return gen_may_p;
1239 }
bool extended_integer_constant_expression_p(expression e)
More extensive than next function.
Definition: expression.c:858

References ENDP, extended_integer_constant_expression_p(), and FOREACH.

+ Here is the call graph for this function:

◆ opgen_must_constant_path()

points_to opgen_must_constant_path ( cell l   __attribute__(__unused__),
cell r   __attribute__(__unused__) 
)

Definition at line 1173 of file constant-path-utils.c.

1174 {
1176  return pt;
1177 }

References points_to_undefined.

◆ opgen_must_module()

bool opgen_must_module ( entity  e1,
entity  e2 
)
Parameters
e11
e22

Definition at line 1190 of file constant-path-utils.c.

1191 {
1192  const char* m1 = entity_module_name(e1);
1193  const char* m2 = entity_module_name(e2);
1194 
1196  return false;
1197  else
1198  return same_string_p(m1, m2);
1199 }

References entity_any_module_p(), entity_module_name(), and same_string_p.

+ Here is the call graph for this function:

◆ opgen_must_name()

bool opgen_must_name ( entity  e1,
entity  e2 
)
Parameters
e11
e22

Definition at line 1212 of file constant-path-utils.c.

1213 {
1214  string n1 = entity_name(e1);
1215  string n2 = entity_name(e2);
1216 
1218  return false;
1219  else
1220  return same_string_p(n1, n2);
1221 }

References entity_abstract_location_p(), entity_name, and same_string_p.

+ Here is the call graph for this function:

◆ opgen_must_type()

type opgen_must_type ( type  t1,
type  t2 
)

the same as opgen_may_type

Parameters
t11
t22

Definition at line 448 of file constant-path-utils.c.

449 {
450  return opgen_may_type(t1,t2);
451 }
type opgen_may_type(type t1, type t2)

References opgen_may_type().

+ Here is the call graph for this function:

◆ opgen_null_location()

set opgen_null_location ( set  L,
cell  r 
)

Definition at line 1254 of file constant-path-utils.c.

1255 {
1257  points_to_rank);
1258  SET_FOREACH(cell, l, L){
1260  set_add_element(gen_null, gen_null, (void*) pt);
1261  }
1262 
1263  return gen_null;
1264 }
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752

References gen_null(), make_approximation_exact(), make_descriptor_none(), make_points_to(), points_to_equal_p(), points_to_rank(), set_add_element(), SET_FOREACH, set_generic_make(), and set_private.

+ Here is the call graph for this function:

◆ opkill_may_constant_path()

bool opkill_may_constant_path ( cell  c1,
cell  c2 
)
Parameters
c11
c22

Definition at line 601 of file constant-path-utils.c.

602 {
603  bool kill_may_p;
604  reference r1 = cell_any_reference(c1);
605  reference r2 = cell_any_reference(c2);
606  type t1 = type_undefined;
607  type t2 = type_undefined;
608  entity v1 = reference_variable(r1);
609  entity v2 = reference_variable(r2);
610  bool type_equal_p = true;
611 
612  if (! type_area_p(entity_type(v1)) && !type_area_p(entity_type(v2))){
613  bool to_be_freed1, to_be_freed2;
614  t1 = points_to_reference_to_type(r1,&to_be_freed1);
615  t2 = points_to_reference_to_type(r2,&to_be_freed2);
616  type_equal_p = opkill_may_type(t1,t2);
617  if(to_be_freed1) free_type(t1);
618  if(to_be_freed2) free_type(t2);
619  }
620  kill_may_p = opkill_may_module(c1,c2) && opkill_may_name(c1,c2) &&
622 
623  return kill_may_p;
624 }
bool opkill_may_module(cell m1, cell m2)
bool opkill_may_vreference(cell c1, cell c2)
FI: really weird and unefficient.
bool opkill_may_type(type t1, type t2)
bool opkill_may_name(cell n1, cell n2)
We define operators for the lattice Name which can be a: -variable of a the program -malloc -NULL /0 ...
#define type_undefined
Definition: ri.h:2883
#define type_area_p(x)
Definition: ri.h:2944

References cell_any_reference(), entity_type, free_type(), opkill_may_module(), opkill_may_name(), opkill_may_type(), opkill_may_vreference(), points_to_reference_to_type(), reference_variable, type_area_p, type_equal_p(), and type_undefined.

Referenced by kill_may_set().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ opkill_may_module()

bool opkill_may_module ( cell  m1,
cell  m2 
)

if the lhs or the rhs is a nowhere location or a null/0 value we generate a pips_user_warning

Parameters
m11
m22

Definition at line 242 of file constant-path-utils.c.

243 {
244  reference r1 = cell_any_reference(m1);
245  reference r2 = cell_any_reference(m2);
246  entity e1 = reference_variable(r1);
247  entity e2 = reference_variable(r2);
248  bool kill_may_p;
249 
250  /* if the lhs or the rhs is a nowhere location or a null/0 value we
251  generate a pips_user_warning */
253  kill_may_p = true;
254  else
255  kill_may_p = same_string_p(entity_name(e1),entity_name(e2));
256 
257  return kill_may_p;
258 }

References cell_any_reference(), entity_any_module_p(), entity_name, reference_variable, and same_string_p.

Referenced by opkill_may_constant_path().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ opkill_may_name()

bool opkill_may_name ( cell  n1,
cell  n2 
)

We define operators for the lattice Name which can be a: -variable of a the program -malloc -NULL /0 -STATIC/STACK/DYNAMIC/HEAP/FORMAL -nowhere/anywhere.

We define the max between 2 names according to the order established by the lattice Name, already done by entity_locations_max() but we have to add a new abstract location for Formal area opkill for the lattice Name tests if 2 names are : -variables of the program then we return the result of the comparison their names. -abstract locations so we return FALSE. Name * Name-> Bool

if(entity_malloc_p(e2)) kill_may_p = false// function entity_malloc_p() have to be defined and different from entity_heap_location_p()

if(entity_malloc_p(e1)) kill_may_p = true// function entity_malloc_p() have to be defined and different from entity_heap_location_p()

Parameters
n11
n22

Definition at line 310 of file constant-path-utils.c.

311 {
312  reference r1 = cell_any_reference(n1);
313  reference r2 = cell_any_reference(n2);
314  entity e1 = reference_variable(r1);
315  entity e2 = reference_variable(r2);
316  bool kill_may_p;
317 
320  pips_user_error("NULL or ANYWHERE locations can't appear as an lvalue\n");
321 
322  if (entity_abstract_location_p(e2)) {
323  if (entity_all_locations_p(e2))
324  kill_may_p = true;
325  if (entity_abstract_location_p(e1)) {
326  if (entity_all_locations_p(e1))
327  kill_may_p = true;
328  else
329  kill_may_p = same_string_p(entity_name(e1), entity_name(e2));
330  }
331  else {
332  /* if(entity_malloc_p(e2)) kill_may_p = false// function
333  entity_malloc_p() have to be defined and different from
334  entity_heap_location_p() */
336  r1 = make_reference(e1,NIL);
337  n1 = make_cell_reference(r1);
338  kill_may_p = opkill_may_name(n1, n2);
339  }
340  }
341  else if ( entity_abstract_location_p(e1) ) {
342  if (entity_all_locations_p(e1))
343  kill_may_p = true;
344  else {
345  /* if(entity_malloc_p(e1)) kill_may_p = true// function
346  entity_malloc_p() have to be defined and different from
347  entity_heap_location_p() */
349  r2 = make_reference(e2,NIL);
350  n2 = make_cell_reference(r2);
351  kill_may_p = opkill_may_name(n1, n2);
352  }
353  }
354  else
355  kill_may_p = same_string_p(entity_name(e1), entity_name(e2));
356 
357  return kill_may_p ;
358 }
entity variable_to_abstract_location(entity v)
returns the smallest abstract locations containing the location of variable v.
bool entity_all_locations_p(entity e)
test if an entity is the top of the lattice

References cell_any_reference(), entity_abstract_location_p(), entity_all_locations_p(), entity_name, entity_nowhere_locations_p(), entity_null_locations_p(), make_cell_reference(), make_reference(), NIL, pips_user_error, reference_variable, same_string_p, and variable_to_abstract_location().

Referenced by opkill_may_constant_path(), and opkill_must_name().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ opkill_may_reference()

bool opkill_may_reference ( cell  c1,
cell  c2 
)
Parameters
c11
c22

Definition at line 454 of file constant-path-utils.c.

455 {
458  bool kill_may_p = true;
459 
460  if (cell_reference_p(c1))
461  r1 = cell_reference(c1);
462  else
464  if (cell_reference_p(c2))
465  r2 = cell_reference(c2);
466  else
468 
470  return kill_may_p;
471  else {
472  kill_may_p = reference_equal_p(r1,r2);
473  return kill_may_p;
474  }
475 }
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define cell_reference_p(x)
Definition: effects.h:467
bool reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
bool store_independent_reference_p(reference r)
Does this reference define the same set of memory locations regardless of the current (environment an...
Definition: expression.c:3108
#define reference_undefined
Definition: ri.h:2302
#define preference_reference(x)
Definition: ri.h:2102

References cell_preference, cell_reference, cell_reference_p, preference_reference, reference_equal_p(), reference_undefined, and store_independent_reference_p().

+ Here is the call graph for this function:

◆ opkill_may_type()

bool opkill_may_type ( type  t1,
type  t2 
)
Parameters
t11
t22

Definition at line 422 of file constant-path-utils.c.

423 {
424  if (!type_unknown_p(t1) && ! type_unknown_p(t2))
425  return type_equal_p(t1,t2);
426  else
427  return false;
428 
429 }

References type_equal_p(), and type_unknown_p.

Referenced by opkill_may_constant_path(), and opkill_must_type().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ opkill_may_vreference()

bool opkill_may_vreference ( cell  c1,
cell  c2 
)

FI: really weird and unefficient.

Also I asummed that vreference was limited to the subscript list... FI->AM: to be checked wrt your dissertation.

Parameters
c11
c22

Definition at line 496 of file constant-path-utils.c.

497 {
498  int i = 0;
499  reference r1 = cell_any_reference(c1);
500  reference r2 = cell_any_reference(c2);
501  entity v1 = reference_variable(r1);
502  entity v2 = reference_variable(r2);
503  list sl1 = NIL, sl2 = NIL;
504  // FI: memory leak? generation of a new string?
505  extern const char* entity_minimal_user_name(entity);
506 
507  // FI: why not compare the entities v1==v2?
509  if ( i==0 ) {
510  sl1 = reference_indices(r1);
511  sl2 = reference_indices(r2);
512  for (;i==0 && !ENDP(sl1) && ! ENDP(sl2) ; POP(sl1), POP(sl2)) {
513  expression se1 = EXPRESSION(CAR(sl1));
514  expression se2 = EXPRESSION(CAR(sl2));
516  i = 0;
517  else if (unbounded_expression_p(se1) && expression_constant_p(se2))
518  i = 0;
519  else if (expression_constant_p(se1) && expression_constant_p(se2) ) {
520  int i1 = expression_to_int(se1);
521  int i2 = expression_to_int(se2);
522  i = i2>i1? 1 : (i2<i1? -1 : 0);
523 
524  // FI: this piece of code seems out of place, if i==0, i==0
525  if ( i==0 ) {
526  string s1 = expression_to_string(se1);
527  string s2 = expression_to_string(se2);
528  i = strcmp(s1, s2);
529  }
530  }
531  else if(field_expression_p(se1) && field_expression_p(se2))
532  i = expression_equal_p(se1,se2)? 0 : 1;
533  }
534  }
535 
536  return (i==0? true: false);
537 }
bool field_expression_p(expression e)
The expression is of kind "a", where "a" is a field of some struct "s".
Definition: expression.c:498
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347

References CAR, cell_any_reference(), ENDP, entity_minimal_user_name(), EXPRESSION, expression_constant_p(), expression_equal_p(), expression_to_int(), expression_to_string(), field_expression_p(), NIL, POP, reference_indices, reference_variable, s1, and unbounded_expression_p().

Referenced by opkill_may_constant_path().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ opkill_must_constant_path()

bool opkill_must_constant_path ( cell  c1,
cell  c2 
)

returns true if c2 kills c1

if (! type_area_p(entity_type(v1)) && !type_area_p(entity_type(v2))){

if (entity_abstract_location_p(v1))

t1 = entity_type(v1);

else

t1 = simple_effect_reference_type(r1);

if (entity_abstract_location_p(v2))

t2 = entity_type(v2);

else

t2 = simple_effect_reference_type(r2);

type_equal_p = opkill_must_type(t1,t2);

}

Parameters
c11
c22

Definition at line 627 of file constant-path-utils.c.

628 {
629  bool kill_must_p;
630  reference r1 = cell_any_reference(c1);
631  reference r2 = cell_any_reference(c2);
632  type t1 = type_undefined;
633  type t2 = type_undefined;
634  //entity v1 = reference_variable(r1);
635  //entity v2 = reference_variable(r2);
636  bool equal_p = true;
637  t1 = points_to_reference_to_type(r1,&equal_p);
638  t2 = points_to_reference_to_type(r2, &equal_p);
639  equal_p = type_equal_p(t1,t2);
640  /* if (! type_area_p(entity_type(v1)) && !type_area_p(entity_type(v2))){ */
641  /* if (entity_abstract_location_p(v1)) */
642  /* t1 = entity_type(v1); */
643  /* else */
644  /* t1 = simple_effect_reference_type(r1); */
645  /* if (entity_abstract_location_p(v2)) */
646  /* t2 = entity_type(v2); */
647  /* else */
648  /* t2 = simple_effect_reference_type(r2); */
649  /* type_equal_p = opkill_must_type(t1,t2); */
650  /* } */
651  kill_must_p = opkill_must_module(c1,c2) && opkill_must_name(c1,c2) &&
652  equal_p && opkill_must_vreference(c1,c2);
653 
654  return kill_must_p;
655 }
bool opkill_must_module(cell m1, cell m2)
bool opkill_must_vreference(cell c1, cell c2)
returns true if c2 must kills c1 because of the subscript expressions
bool opkill_must_name(cell n1, cell n2)

References cell_any_reference(), opkill_must_module(), opkill_must_name(), opkill_must_vreference(), points_to_reference_to_type(), type_equal_p(), and type_undefined.

Referenced by kill_must_set().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ opkill_must_module()

bool opkill_must_module ( cell  m1,
cell  m2 
)
Parameters
m11
m22

Definition at line 260 of file constant-path-utils.c.

261 {
262  reference r1 = cell_any_reference(m1);
263  reference r2 = cell_any_reference(m2);
264  entity e1 = reference_variable(r1);
265  entity e2 = reference_variable(r2);
266  bool kill_must_p;
267 
269  kill_must_p = false;
270  else
271  kill_must_p = same_string_p(entity_name(e1),entity_name(e2));
272 
273  return kill_must_p;
274 }

References cell_any_reference(), entity_any_module_p(), entity_name, reference_variable, and same_string_p.

Referenced by opkill_must_constant_path().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ opkill_must_name()

bool opkill_must_name ( cell  n1,
cell  n2 
)

if(entity_malloc_p(e2)) kill_may_p = false// function entity_malloc_p() have to be defined and different from entity_heap_location_p()

if(entity_malloc_p(e1)) kill_may_p = true// function entity_malloc_p() have to be defined and different from entity_heap_location_p()

Parameters
n11
n22

Definition at line 361 of file constant-path-utils.c.

362 {
363  reference r1 = cell_any_reference(n1);
364  reference r2 = cell_any_reference(n2);
365  entity e1 = reference_variable(r1);
366  entity e2 = reference_variable(r2);
367  bool kill_must_p;
368 
371  pips_user_error("NULL or ANYWHERE locations can't appear as an lvalue\n");
372 
373  if (entity_abstract_location_p(e2)) {
374  if (entity_all_locations_p(e2))
375  kill_must_p = false;
376  if (entity_abstract_location_p(e1)) {
377  if(entity_all_locations_p(e1))
378  kill_must_p = false;
379  else
380  kill_must_p = same_string_p(entity_name(e1), entity_name(e2));
381  }
382  else {
383  /* if(entity_malloc_p(e2)) kill_may_p = false// function
384  entity_malloc_p() have to be defined and different from
385  entity_heap_location_p() */
387  r1 = make_reference(e1,NIL);
388  n1 = make_cell_reference(r1);
389  kill_must_p = opkill_may_name(n1, n2);
390  }
391  }
392  else if ( entity_abstract_location_p(e1) ) {
393  if (entity_all_locations_p(e1))
394  kill_must_p = false;
395  else {
396  /* if(entity_malloc_p(e1)) kill_may_p = true// function
397  entity_malloc_p() have to be defined and different from
398  entity_heap_location_p() */
400  r2 = make_reference(e2,NIL);
401  n2 = make_cell_reference(r2);
402  kill_must_p = opkill_may_name(n1, n2);
403  }
404  }
405  else
406  kill_must_p = same_string_p(entity_name(e1), entity_name(e2));
407 
408  return kill_must_p ;
409 }

References cell_any_reference(), entity_abstract_location_p(), entity_all_locations_p(), entity_name, entity_nowhere_locations_p(), entity_null_locations_p(), make_cell_reference(), make_reference(), NIL, opkill_may_name(), pips_user_error, reference_variable, same_string_p, and variable_to_abstract_location().

Referenced by opkill_must_constant_path().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ opkill_must_reference()

bool opkill_must_reference ( cell  c1,
cell  c2 
)
Parameters
c11
c22

Definition at line 478 of file constant-path-utils.c.

479 {
480  reference r1 = cell_any_reference(c1);
481  reference r2 = cell_any_reference(c2);
482  bool kill_must_p = false;
483 
485  return kill_must_p;
486  else {
487  kill_must_p = reference_equal_p(r1,r2);
488  return kill_must_p;
489  }
490 }

References cell_any_reference(), reference_equal_p(), and store_independent_reference_p().

+ Here is the call graph for this function:

◆ opkill_must_type()

bool opkill_must_type ( type  t1,
type  t2 
)

opkill_must_type is the same as op_kill_may_type...

Parameters
t11
t22

Definition at line 432 of file constant-path-utils.c.

433 {
434  return opkill_may_type(t1,t2);
435 }

References opkill_may_type().

+ Here is the call graph for this function:

◆ opkill_must_vreference()

bool opkill_must_vreference ( cell  c1,
cell  c2 
)

returns true if c2 must kills c1 because of the subscript expressions

This function should be rewritten from scratch, with a defined semantics for "*" as a subscript and possibly a larger use of expression_equal_p(). Also, we need to specify if the scopes for each rereference are equal or not.

Parameters
c11
c22

Definition at line 546 of file constant-path-utils.c.

547 {
548  int i = 0;
549  reference r1 = cell_any_reference(c1);
550  reference r2 = cell_any_reference(c2);
551  entity v1 = reference_variable(r1);
552  entity v2 = reference_variable(r2);
553  list sl1 = NIL, sl2 = NIL;
554  // FI: memory leak? generation of a new string?
555  extern const char* entity_minimal_user_name(entity);
556 
557  // FI: this step could be assumed performed earlier
559  if (i==0) {
560  sl1 = reference_indices(r1);
561  sl2 = reference_indices(r2);
562  for (;i==0 && !ENDP(sl1) && ! ENDP(sl2) ; POP(sl1), POP(sl2)){
563  expression se1 = EXPRESSION(CAR(sl1));
564  expression se2 = EXPRESSION(CAR(sl2));
566  //i = 0;
567  i = 1;
568  }
569  else if(expression_constant_p(se1) && unbounded_expression_p(se2)){
570  //i = 0; could be true if * is interpreted as "forall"
571  i = 1;
572  }
573  else if (expression_constant_p(se1) && expression_constant_p(se2)){
574  int i1 = expression_to_int(se1);
575  int i2 = expression_to_int(se2);
576  i = i2>i1? 1 : (i2<i1? -1 : 0);
577  if (i==0){ // FI->AM: I do not understand this step
578  string s1 = expression_to_string(se1);
579  string s2 = expression_to_string(se2);
580  i = strcmp(s1, s2);
581  }
582  }
583  else {
584  // FI->AM: very dangerous; only true if both references appear
585  // exactly in the same scope; and "*" were not dealt with!
587  i = 1;
588  else {
589  i = expression_equal_p(se1, se2)? 0 : 1;
590  }
591  }
592  }
593  }
594 
595  return (i==0? true: false);
596 }

References CAR, cell_any_reference(), ENDP, entity_minimal_user_name(), EXPRESSION, expression_constant_p(), expression_equal_p(), expression_to_int(), expression_to_string(), NIL, POP, reference_indices, reference_variable, s1, and unbounded_expression_p().

Referenced by opkill_must_constant_path().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ points_to_anywhere()

set points_to_anywhere ( list  lhs_list,
set  input 
)

lhs_path matches the kill set.

input - kill

if the lhs_set or the rhs set contains more than an element, we set the approximation to MAY.

Computing the gen set

create a new points to with as source the current element of lhs_set and sink the null value .

gen + input_kill_diff

Parameters
lhs_lisths_list
inputnput

Definition at line 122 of file constant-path-utils.c.

123 {
124  /* lhs_path matches the kill set.*/
134 
135  SET_FOREACH ( points_to, p, input ) {
136  FOREACH ( cell, c, lhs_list ) {
138  set_add_element(kill, kill, p);
139  }
140  }
141 
142  /* input - kill */
143  set_difference(input_kill_diff, input, kill);
144 
145  /* if the lhs_set or the rhs set contains more than an element, we
146  set the approximation to MAY. */
147  if ( (int)gen_length(lhs_list) > 1 )// || set_size(rhs_set)>1)
149 
150  /* Computing the gen set*/
151  FOREACH ( cell, c, lhs_list ) {
152  /* create a new points to with as source the current
153  element of lhs_set and sink the null value .*/
155  reference r = make_reference(e, NIL);
156  cell sink = make_cell_reference(r);
157  points_to pt_to = make_points_to(c, sink, a, make_descriptor_none());
158  set_add_element(gen, gen, (void*)pt_to);
159  }
160  /* gen + input_kill_diff*/
161  set_union(res, gen, input_kill_diff);
162 
163  return res;
164 }
#define ANYWHERE_LOCATION
static int input(void)
set set_difference(set, const set, const set)
Definition: set.c:256
static statement gen(int what, entity src, entity trg, entity lid, entity proc, entity(*create_src)(), entity(*create_trg)(), Psysteme sr, list ldiff)
arguments: all that may be useful to generate some code
Definition: remapping.c:498

References ANYWHERE_LOCATION, entity_all_xxx_locations(), FOREACH, gen(), gen_length(), input(), make_approximation_exact(), make_approximation_may(), make_cell_reference(), make_descriptor_none(), make_points_to(), make_reference(), NIL, points_to_compare_cell(), points_to_equal_p(), points_to_rank(), points_to_source, set_add_element(), set_difference(), SET_FOREACH, set_generic_make(), set_private, and set_union().

Referenced by list_assignment_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ points_to_anywhere_typed()

set points_to_anywhere_typed ( list  lhs_list,
set  input 
)

Already exists in points_to_general_algorithm.c, to be removed later...

iterate over the lhs_set, if it contains more than an element approximations are set to MAY, otherwise it's set to EXACT Set the sink to anywhere .

input - kill

if the lhs_set or the rhs set contains more than an element, we set the approximation to MAY.

Computing the gen set

create a new points to with as source the current element of lhs_set and sink the null value .

Parameters
lhs_lisths_list
inputnput

Definition at line 75 of file constant-path-utils.c.

76 {
86 
88  FOREACH(cell, c, lhs_list) {
90  set_add_element(kill, kill, p);
91  }
92  }
93 
94  /* input - kill */
95  set_difference(input_kill_diff, input, kill);
96 
97  /* if the lhs_set or the rhs set contains more than an element, we
98  set the approximation to MAY. */
99  if((int)gen_length(lhs_list) > 1)// || set_size(rhs_set)>1)
101 
102  /* Computing the gen set*/
103  FOREACH(cell, c, lhs_list) {
104  /* create a new points to with as source the current
105  element of lhs_set and sink the null value .*/
107  entity er = reference_variable(cr);
108  type t = entity_type(er);
110  reference r = make_reference(e, NIL);
111  cell sink = make_cell_reference(r);
112  points_to pt_to = make_points_to(c, sink, a, make_descriptor_none());
113  set_add_element(gen, gen, (void*)pt_to);
114  }
115 
116  set_union(res, gen, input_kill_diff);
117 
118  return res;
119 }

References ANYWHERE_LOCATION, cell_any_reference(), entity_all_xxx_locations_typed(), entity_type, FOREACH, gen(), gen_length(), input(), make_approximation_exact(), make_approximation_may(), make_cell_reference(), make_descriptor_none(), make_points_to(), make_reference(), NIL, points_to_compare_cell(), points_to_equal_p(), points_to_rank(), points_to_source, reference_variable, set_add_element(), set_difference(), SET_FOREACH, set_generic_make(), set_private, and set_union().

Referenced by list_assignment_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ points_to_independent_store()

set points_to_independent_store ( set  s)

Definition at line 1273 of file constant-path-utils.c.

1274 {
1276  points_to_rank);
1277  bool changed = false;
1278 
1279  SET_FOREACH(points_to, pt, s){
1280  cell source = points_to_source(pt);
1281  cell sink = points_to_sink(pt);
1282  cell new_source = simple_cell_to_store_independent_cell(source, &changed);
1283  cell new_sink = simple_cell_to_store_independent_cell(sink, &changed);
1284  points_to npt = make_points_to(new_source, new_sink, points_to_approximation(pt),points_to_descriptor(pt));
1285  set_add_element(res, res, (void*) npt);
1286  }
1287 
1288  return res;
1289 }
#define points_to_descriptor(x)

References make_points_to(), points_to_approximation, points_to_descriptor, points_to_equal_p(), points_to_rank(), points_to_sink, points_to_source, set_add_element(), SET_FOREACH, set_generic_make(), set_private, and simple_cell_to_store_independent_cell().

Referenced by any_loop_to_points_to(), and new_any_loop_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ points_to_may_filter()

set points_to_may_filter ( set  in)

returns a set which contains all the MAY points to

Parameters
inn

Definition at line 716 of file constant-path-utils.c.

717 {
720 
721  SET_FOREACH(points_to, pt, in){
723  set_add_element(in_may, in_may, (void*)pt);
724  }
725  return in_may;
726 }
#define approximation_may_p(x)
Definition: effects.h:363

References approximation_may_p, points_to_approximation, points_to_equal_p(), points_to_rank(), set_add_element(), SET_FOREACH, set_generic_make(), and set_private.

Referenced by list_assignment_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ points_to_must_filter()

set points_to_must_filter ( set  in)

returns a set which contains all the EXACT points to

Parameters
inn

Definition at line 729 of file constant-path-utils.c.

730 {
733  SET_FOREACH(points_to, pt, in){
735  set_add_element(in_must, in_must, (void*)pt);
736  }
737  return in_must;
738 }

References approximation_exact_p, points_to_approximation, points_to_equal_p(), points_to_rank(), set_add_element(), SET_FOREACH, set_generic_make(), and set_private.

Referenced by list_assignment_to_points_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ points_to_nowhere()

set points_to_nowhere ( list  lhs_list,
set  input 
)

arg1: list of cells arg2: set of points-to Create a points-to set with elements of lhs_list as source and NOWHERE as sink.

Iterate over input and kill all points-to relations where sinks are elements of lhs_list.

if the lhs_set or the rhs set contains more than an element, we set the approximation to MAY.

Computing the gen set

Parameters
lhs_lisths_list
inputnput

Definition at line 1351 of file constant-path-utils.c.

1352 {
1354  points_to_rank);
1356  points_to_rank);
1358  points_to_rank);
1360  points_to_rank);
1362 
1363  SET_FOREACH(points_to, p, input) {
1364  FOREACH(cell, c, lhs_list) {
1365  if(points_to_source(p) == c)
1366  set_add_element(kill, kill, p);
1367  }
1368  }
1369  set_difference(input_kill_diff, input, kill);
1370  /* if the lhs_set or the rhs set contains more than an element, we
1371  set the approximation to MAY. */
1372  if((int)gen_length(lhs_list) > 1)// || set_size(rhs_set)>1)
1373  a = make_approximation_may();
1374 
1375  /* Computing the gen set */
1376  FOREACH(cell, c, lhs_list) {
1377  cell sink = make_nowhere_cell();
1379  set_add_element(gen, gen, (void*)pt_to);
1380  }
1381  free_approximation(a);
1382  set_union(res, gen, input_kill_diff);
1383 
1384  return res;
1385 }
approximation copy_approximation(approximation p)
APPROXIMATION.
Definition: effects.c:132
void free_approximation(approximation p)
Definition: effects.c:135

References copy_approximation(), FOREACH, free_approximation(), gen(), gen_length(), input(), make_approximation_exact(), make_approximation_may(), make_descriptor_none(), make_nowhere_cell(), make_points_to(), points_to_equal_p(), points_to_rank(), points_to_source, set_add_element(), set_difference(), SET_FOREACH, set_generic_make(), set_private, and set_union().

+ Here is the call graph for this function:

◆ subscript_expression_p()

bool subscript_expression_p ( expression  e)

Definition at line 752 of file constant-path-utils.c.

753 {
755 }
#define syntax_subscript_p(x)
Definition: ri.h:2743

References expression_syntax, and syntax_subscript_p.

◆ unique_location_cell_p()

bool unique_location_cell_p ( cell  c)

Does cell "c" represent a unique memory location or a set of memory locations?

This is key to decide if a points-to arc is a must or a may arc.

Is it always possible to decide when heap abstract locations are concerned?

See also cell_abstract_location_p()

Definition at line 980 of file constant-path-utils.c.

981 {
982  bool unique_p = !anywhere_cell_p(c)
984  // FI: typed or not?
985  // FI: how do you know when heap cells are unique and when they
986  // represent a set of cells?
987  && !heap_cell_p(c);
988 
989  // FI: how do you deal with arrays of pointers?
990  if(unique_p) {
992  list sl = reference_indices(r);
993  FOREACH(EXPRESSION, s, sl) {
994  if(unbounded_expression_p(s)) {
995  unique_p = false;
996  break;
997  }
998  }
999  }
1000  return unique_p;
1001 }
bool cell_typed_anywhere_locations_p(cell c)
test if a cell is the bottom of the lattice
bool anywhere_cell_p(cell)
Is it an anywhere cell?
Definition: effects.c:367
bool heap_cell_p(cell)
Any heap cell, more or less abstract or typed.
Definition: effects.c:420

References anywhere_cell_p(), cell_any_reference(), cell_typed_anywhere_locations_p(), EXPRESSION, FOREACH, heap_cell_p(), reference_indices, and unbounded_expression_p().

Referenced by gen_may_constant_paths(), and gen_must_constant_paths().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: