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

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 For strdup and asprintf: More...
 

Functions

void points_to_forward_translation ()
 -----------------------------—Interprocedural Points-to Analysis--------------------— More...
 
void points_to_backward_translation ()
 
set formal_points_to_parameter (cell c)
 We want a recursive descent on the type of the formal parameter, once we found a pointer type we beguin a recursive descent until founding a basic case. More...
 
entity create_stub_entity (entity e, string fs, type t)
 Allocate a stub entity "stub" for entity "e" and with type "t". More...
 
cell create_scalar_stub_sink_cell (entity v, type st, type pt, int d, list sl, string fs)
 Create a stub entity "se" for entity "v" with type "t" and return a cell based on a reference to the stub entity "se" with "d" unbounded subscripts to account for the dimension of the source and a zero subscript for implicit array. More...
 
int points_to_indices_to_array_index_number (list sl)
 Count the number of array indices and ignore the field subscripts. More...
 
void points_to_indices_to_unbounded_indices (list sl)
 FI: probably a duplicate... More...
 
list points_to_indices_to_subscript_indices (list ptsl)
 Generate a new subscript list. More...
 
string reference_to_field_disambiguator (reference r)
 Build an ASCII string to disambiguate the different field paths that may exist in similar references. More...
 
points_to create_stub_points_to (cell c, type unused_st __attribute__((__unused__)), bool exact_p)
 points_to create_stub_points_to(cell c, bool exact_p) More...
 
points_to create_advanced_stub_points_to (cell c, type t, bool exact_p)
 Take into account the POINTS_TO_STRICT_POINTER_TYPE to allocate a sink cell of type "t" if the strictness is requested and of type "array of t" if not. More...
 
points_to create_pointer_to_array_stub_points_to (cell c, type t, bool exact_p)
 To create the points-to stub associated to the formal parameter, the sink name is a concatenation of the formal parmater and the POINTS_TO_MODULE_NAME. More...
 
set pointer_formal_parameter_to_stub_points_to (type pt, cell c)
 Input : a formal parameter which is a pointer and its type. More...
 
set derived_formal_parameter_to_stub_points_to (type pt, cell c)
 Input : a formal parameter which has a derived type (FI, I guess). More...
 
set typedef_formal_parameter_to_stub_points_to (type pt, cell c)
 Input : a formal parameter which is a typedef. More...
 
set array_formal_parameter_to_stub_points_to (type t, cell c)
 Type "t" is supposed to be a concrete type. More...
 

Variables

static int pointer_index = 1
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

For strdup and asprintf:

Definition at line 28 of file points_to_init_analysis.c.

Function Documentation

◆ array_formal_parameter_to_stub_points_to()

set array_formal_parameter_to_stub_points_to ( type  t,
cell  c 
)

Type "t" is supposed to be a concrete type.

Type "t" may be modified: no.

Cell "c" is copied.

The dimensions of type "t" are forgotten. They are retrieved later from the type of the entity references in cell "c".

Add an artificial dimension for pointer arithmetic

Definition at line 1116 of file points_to_init_analysis.c.

1117 {
1120  points_to_rank);
1122 
1123  if(basic_pointer_p(fpb)) {
1125  entity e = reference_variable(r);
1126  reference ref = make_reference(e, NULL);
1128  cell cel = make_cell_reference(ref);
1129  type pt = copy_type(basic_pointer(fpb));
1130 
1131  bool strict_p = get_bool_property("POINTS_TO_STRICT_POINTER_TYPES");
1132  if(scalar_type_p(pt) && !strict_p) {
1133  /* Add an artificial dimension for pointer arithmetic */
1136  dimension d = make_dimension(l, u, NIL);
1137  variable ptv = type_variable(pt);
1138  variable_dimensions(ptv) = CONS(DIMENSION, d, NIL);
1139  }
1140 
1141  bool exact_p = !get_bool_property("POINTS_TO_NULL_POINTER_INITIALIZATION");
1142  points_to pt_to = create_stub_points_to(cel, pt, exact_p);
1143  //cell source = points_to_source(pt_to);
1144  pt_in = set_add_element(pt_in, pt_in,
1145  (void*) pt_to );
1146  }
1147 
1148  return pt_in;
1149 
1150 }
cell make_cell_reference(reference _field_)
Definition: effects.c:293
bool reference_consistent_p(reference p)
Definition: ri.c:2056
type copy_type(type p)
TYPE.
Definition: ri.c:2655
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#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
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
@ 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
points_to create_stub_points_to(cell c, type unused_st __attribute__((__unused__)), bool exact_p)
points_to create_stub_points_to(cell c, bool exact_p)
expression make_unbounded_expression()
Definition: expression.c:4339
expression make_zero_expression(void)
Make a zero expression.
Definition: expression.c:1212
bool scalar_type_p(type)
Definition: type.c:2955
#define basic_pointer(x)
Definition: ri.h:637
#define reference_variable(x)
Definition: ri.h:2326
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#define variable_dimensions(x)
Definition: ri.h:3122
#define variable_basic(x)
Definition: ri.h:3120
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References basic_pointer, basic_pointer_p, cell_any_reference(), CONS, copy_type(), create_stub_points_to(), DIMENSION, get_bool_property(), make_cell_reference(), make_dimension(), make_reference(), make_unbounded_expression(), make_zero_expression(), NIL, points_to_equal_p(), points_to_rank(), ref, reference_consistent_p(), reference_variable, scalar_type_p(), set_add_element(), set_generic_make(), set_private, type_variable, variable_basic, and variable_dimensions.

Referenced by formal_points_to_parameter().

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

◆ create_advanced_stub_points_to()

points_to create_advanced_stub_points_to ( cell  c,
type  t,
bool  exact_p 
)

Take into account the POINTS_TO_STRICT_POINTER_TYPE to allocate a sink cell of type "t" if the strictness is requested and of type "array of t" if not.

assume that pointers to scalars always points towards an array of unknown dimension.

Parameters
exact_pxact_p

Definition at line 688 of file points_to_init_analysis.c.

689 {
690  pips_internal_error("This function is no longer used. Functionality moved into create_stub_points_to directly...\n");
692  bool strict_p = get_bool_property("POINTS_TO_STRICT_POINTER_TYPES");
693  if(true || strict_p || array_type_p(t))
694  pt = create_stub_points_to(c, t, exact_p);
695  else {
696  /* assume that pointers to scalars always points towards an array
697  of unknown dimension. */
698  type at = type_to_array_type(t);
699  pt = create_stub_points_to(c, at, exact_p);
700  // FI: I do not know if we should free t [and/or at]
701  }
702  return pt;
703 }
#define pips_internal_error
Definition: misc-local.h:149
#define points_to_undefined
bool array_type_p(type)
Definition: type.c:2942
type type_to_array_type(type)
convert a type "t" into a newly allocated array type "at" whose elements are of type "t",...
Definition: type.c:5653

References array_type_p(), create_stub_points_to(), get_bool_property(), pips_internal_error, points_to_undefined, and type_to_array_type().

+ Here is the call graph for this function:

◆ create_pointer_to_array_stub_points_to()

points_to create_pointer_to_array_stub_points_to ( cell  c,
type  t,
bool  exact_p 
)

To create the points-to stub associated to the formal parameter, the sink name is a concatenation of the formal parmater and the POINTS_TO_MODULE_NAME.

Parameters
exact_pxact_p

Definition at line 709 of file points_to_init_analysis.c.

710 {
711  list l_ind = NIL;
712  basic bb = basic_undefined;
716  reference sink_ref = reference_undefined;
717  cell source_cell = copy_cell(c);
718  reference r = cell_any_reference(source_cell);
719  entity e = reference_variable(r);
720  const char * en = entity_user_name(e);
721  string s = NULL;
722  if( formal_parameter_p(e) ) {
724  int off = formal_offset(f);
725  s = strdup(concatenate("_", en,"_", int2a(off), NULL));
726  }
727  else {
728  char *suffix = strrchr(en,'_');
729  s = strdup(concatenate( en, suffix, NULL ));
730  }
731 
732  string formal_name = strdup(concatenate(get_current_module_name() ,MODULE_SEP_STRING, s, NULL));
733  entity stub_entity = gen_find_entity(formal_name);
734  type pt = type_undefined;
735  bool type_strict_p = get_bool_property("POINTS_TO_STRICT_POINTER_TYPES");
736  bb = variable_basic(type_variable(t));
738  basic base = copy_basic(bb);
739  FOREACH(DIMENSION, d, l_dim){
740  l = dimension_lower(d);
741  u = dimension_upper(d);
742  l_ind = CONS(EXPRESSION, l, NIL);
743  l_ind = gen_nconc(l_ind, (CONS(EXPRESSION, u, NIL)));
744  }
745 
746 
747  if(type_strict_p)
748  pt = make_type_variable(
750  CONS(DIMENSION,
752  ex,
753  NIL),
754  NIL),
755  NIL));
756  else
757  pt = copy_type(t);
758 
759  if(entity_undefined_p(stub_entity)) {
762  // FI->AM: weird, it is redone when the entity already exists
765  DummyTarget,
767  stub_entity = make_entity(formal_name,
768  pt,
769  // FI->AM: if it is made rom, then
770  // the entitY is no longer
771  // recognized by entity_stub_sink_p()
772  // make_storage_rom(),
773  rs,
775  }
776 
777  if(type_strict_p)
778  sink_ref = make_reference(stub_entity, CONS(EXPRESSION, int_to_expression(0), NIL));
779  else if((int)gen_length(l_dim)>1){
780  sink_ref = make_reference(stub_entity,l_ind);
781  }
782  else {
783  // sink_ref = make_reference(stub_entity, CONS(EXPRESSION, int_to_expression(0), NIL));
784  // FI: no reason to index an array; see "p = &a;"
785  sink_ref = make_reference(stub_entity, NIL);
786  }
787 
788  cell sink_cell = make_cell_reference(sink_ref);
789  approximation rel =
791  points_to pt_to = make_points_to(source_cell, sink_cell, rel,
793  pointer_index ++;
794  return pt_to;
795 }
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)
value make_value_unknown(void)
Definition: ri.c:2847
type make_type_variable(variable _field_)
Definition: ri.c:2715
entity gen_find_entity(char *s)
Definition: ri.c:2551
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
storage make_storage_ram(ram _field_)
Definition: ri.c:2279
bdt base
Current expression.
Definition: bdt_read_paf.c:100
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
size_t gen_length(const list l)
Definition: list.c:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#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 POINTER_DUMMY_TARGETS_AREA_LOCAL_NAME
Definition: naming-local.h:77
#define MODULE_SEP_STRING
Definition: naming-local.h:30
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static int pointer_index
#define make_entity(n, t, s, i)
#define UNKNOWN_RAM_OFFSET
@ ENTITY_POINTER_DUMMY_TARGETS_AREA
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
bool formal_parameter_p(entity)
Definition: variable.c:1489
#define formal_offset(x)
Definition: ri.h:1408
#define reference_undefined
Definition: ri.h:2302
#define dimension_lower(x)
Definition: ri.h:980
#define entity_storage(x)
Definition: ri.h:2794
#define storage_formal(x)
Definition: ri.h:2524
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define basic_undefined
Definition: ri.h:556
#define entity_undefined_p(x)
Definition: ri.h:2762
#define expression_undefined
Definition: ri.h:1223
#define dimension_upper(x)
Definition: ri.h:982
#define type_undefined
Definition: ri.h:2883
#define entity_kind(x)
Definition: ri.h:2798
char * strdup()
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
char * int2a(int)
util.c
Definition: util.c:42

References base, basic_undefined, cell_any_reference(), concatenate(), CONS, copy_basic(), copy_cell(), copy_type(), DIMENSION, dimension_lower, dimension_upper, entity_kind, ENTITY_POINTER_DUMMY_TARGETS_AREA, entity_storage, entity_undefined_p, entity_user_name(), EXPRESSION, expression_undefined, f(), FindOrCreateEntity(), FOREACH, formal_offset, formal_parameter_p(), gen_find_entity(), gen_length(), gen_nconc(), get_bool_property(), get_current_module_entity(), get_current_module_name(), int2a(), int_to_expression(), make_approximation_exact(), make_approximation_may(), make_cell_reference(), make_descriptor_none(), make_dimension(), make_entity, make_points_to(), make_ram(), make_reference(), make_storage_ram(), make_type_variable(), make_unbounded_expression(), make_value_unknown(), make_variable(), MODULE_SEP_STRING, NIL, POINTER_DUMMY_TARGETS_AREA_LOCAL_NAME, pointer_index, reference_undefined, reference_variable, storage_formal, strdup(), type_undefined, type_variable, UNKNOWN_RAM_OFFSET, variable_basic, and variable_dimensions.

Referenced by pointer_formal_parameter_to_stub_points_to().

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

◆ create_scalar_stub_sink_cell()

cell create_scalar_stub_sink_cell ( entity  v,
type  st,
type  pt,
int  d,
list  sl,
string  fs 
)

Create a stub entity "se" for entity "v" with type "t" and return a cell based on a reference to the stub entity "se" with "d" unbounded subscripts to account for the dimension of the source and a zero subscript for implicit array.

Type "pt" is the theoretically expected type for the reference "sink_ref" within the returned cell, "sink_cell". We assert "pt==points_to_cell_to_type(sink_cell)".

Type "t" must account for the extra "d" dimensions.

The type strictness is handled by the caller.

The name of the function is misleading. It should be "create_stub_sink_cell"... but in fact is does not handle the struct case because struct can contain may different pointers, directly or indirectly, depending on fields. This function is ok if v a pointer or an array of pointers, but not if v is a struct.

The function is called four times from create_stub_points_to().

When scalars are used, we should have "d==0" and "td==0" and hence "sl==NIL"

FI: use 0 for all proper target dimensions

FI: adding 0 subscripts is similar to a dereferencing. We do not know at this level if the dereferencing has been requested. See pointer_reference02. The handling fo eval_p must be modified correspondingly by adding 0 subscripts when the source is an array. Or evaluation must be skipped.

Parameters
stt
ptt
sll
fss

Definition at line 267 of file points_to_init_analysis.c.

273 {
274  //type vt = entity_basic_concrete_type(v);
275  //pips_assert("v is not a struct", !struct_type_p(vt));
276  type t = type_undefined;
277 
278  if(type_void_p(st))
279  t = MakeTypeOverloaded();
280  else
281  t = copy_type(st);
282 
283  entity stub_entity = create_stub_entity(v, fs, t);
284  reference sink_ref = reference_undefined;
285 
286  ifdebug(1) {
287  pips_debug(1, "Entity \"%s\"\n", entity_local_name(v));
288  pips_debug(1, "Stub type: "); print_type(t);
289  fprintf(stderr, "\n");
290  pips_debug(1, "Pointed type: "); print_type(pt);
291  fprintf(stderr, "\n");
292  pips_debug(1, "Number of source dimensions: %d\n", d);
293  fprintf(stderr, "\n");
294  }
295 
296  if(type_functional_p(t)) {
297  pips_assert("The source dimension is zero if the target is not an array", d==0);
298  sink_ref = make_reference(stub_entity, NIL);
299  }
300  else if(type_variable_p(t)) {
301  /* When scalars are used, we should have "d==0" and "td==0" and hence "sl==NIL" */
303  pips_assert("The target dimension is greater than or equal to the source dimension", d<=td);
304  int i;
305  //if(false) {
306  if(true) {
307  list tl = NIL;
308  /* FI: use 0 for all proper target dimensions */
309  /* FI: adding 0 subscripts is similar to a dereferencing. We do
310  not know at this level if the dereferencing has been
311  requested. See pointer_reference02. The handling fo eval_p must
312  be modified correspondingly by adding 0 subscripts when the
313  source is an array. Or evaluation must be skipped. */
314  for(i=d;i<td;i++) {
315  tl = CONS(EXPRESSION, make_zero_expression(), tl);
316  }
317  sl = gen_nconc(sl, tl);
318  sink_ref = make_reference(stub_entity, sl);
319  }
320  else {
321  sink_ref = make_reference(stub_entity, sl);
322  bool e_to_be_freed;
323  type ept = points_to_reference_to_type(sink_ref, &e_to_be_freed);
324  i = d;
325  while(!array_pointer_type_equal_p(pt, ept)
326  && !(type_void_p(pt) && overloaded_type_p(ept))
327  && i<td) {
328  if(e_to_be_freed) free_type(ept);
330  reference_indices(sink_ref) =
331  gen_nconc(reference_indices(sink_ref), tl);
332  ept = points_to_reference_to_type(sink_ref, &e_to_be_freed);
333  i++;
334  }
335  if(!array_pointer_type_equal_p(pt, ept)
336  && !(type_void_p(pt) && overloaded_type_p(ept)))
337  pips_internal_error("The stub and expected types are incompatible.\n");
338  else {
339  ;
340  }
341  if(e_to_be_freed) free_type(ept);
342  }
343  }
344  else if(type_void_p(t)) {
345  pips_assert("Implemented", false);
346  }
347 
348  cell sink_cell = make_cell_reference(sink_ref);
349 
350  ifdebug(1) {
351  type ept = points_to_cell_to_concrete_type(sink_cell);
352  if(!array_pointer_type_equal_p(pt, ept)
353  && !(type_void_p(pt) || overloaded_type_p(ept))) {
354  bool ok_p = false;
355  if(array_type_p(pt)) {
356  if(!array_type_p(ept)) {
357  // FI: do not forget the [0] subscript added...
359  basic bept = variable_basic(type_variable(ept));
360  if(basic_equal_p(bpt, bept))
361  ok_p = true; // to be able to breakpointx
362  }
363  }
364  if(!ok_p) {
365  pips_debug(1, "pt = "); print_type(pt);
366  fprintf(stderr, "\n");
367  pips_debug(1, "ept = "); print_type(ept);
368  fprintf(stderr, "\n");
369  pips_internal_error("Effective type of sink cell does not match its expected type\n");
370  }
371  }
372  pips_debug(1, "source entity: \"%s\", sink_cell: ", entity_user_name(v));
373  print_points_to_cell(sink_cell);
374  fprintf(stderr, "\n");
375  pips_assert("sink_cell is consistent", cell_consistent_p(sink_cell));
376  }
377 
378  return sink_cell;
379 }
bool cell_consistent_p(cell p)
Definition: effects.c:255
void free_type(type p)
Definition: ri.c:2658
type points_to_cell_to_concrete_type(cell)
Definition: type.c:676
type points_to_reference_to_type(reference, bool *)
FI: I need more generality than is offered by cell_to_type()
Definition: type.c:527
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
entity create_stub_entity(entity e, string fs, type t)
Allocate a stub entity "stub" for entity "e" and with type "t".
#define print_points_to_cell(x)
Definition: print.c:377
void print_type(type)
For debugging.
Definition: type.c:111
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
int variable_dimension_number(variable)
Definition: type.c:5632
bool basic_equal_p(basic, basic)
Definition: type.c:927
bool array_pointer_type_equal_p(type, type)
assume that a pointer to type x is equal to a 1-D array of x
Definition: type.c:609
type MakeTypeOverloaded(void)
Definition: type.c:107
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
#define type_functional_p(x)
Definition: ri.h:2950
#define type_void_p(x)
Definition: ri.h:2959
#define reference_indices(x)
Definition: ri.h:2328
#define type_variable_p(x)
Definition: ri.h:2947
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define ifdebug(n)
Definition: sg.c:47

References array_pointer_type_equal_p(), array_type_p(), basic_equal_p(), cell_consistent_p(), CONS, copy_type(), create_stub_entity(), entity_local_name(), entity_user_name(), EXPRESSION, fprintf(), free_type(), gen_nconc(), ifdebug, make_cell_reference(), make_reference(), make_zero_expression(), MakeTypeOverloaded(), NIL, overloaded_type_p(), pips_assert, pips_debug, pips_internal_error, points_to_cell_to_concrete_type(), points_to_reference_to_type(), print_points_to_cell, print_type(), reference_indices, reference_undefined, type_functional_p, type_undefined, type_variable, type_variable_p, type_void_p, variable_basic, and variable_dimension_number().

Referenced by create_stub_points_to().

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

◆ create_stub_entity()

entity create_stub_entity ( entity  e,
string  fs,
type  t 
)

Allocate a stub entity "stub" for entity "e" and with type "t".

Abort if "stub" already exists.

It seems that type "t" could be derived from "e" since it should be the pointed type of "e"'s type, but it is not at all the case in general. Variable e is used to build a reference and the type pointed by the reference may be different when arrays of structs of arrays of structs are involved.

FI: I assume all unknown offsets defined in ri-util-local.h to be strictly negative.

FI: we could use a 0 as default offset for clarity?

FI: we are in deep trouble because the stub entity has already been created... but we have no idea if it is or not the entity we wanted as it depends on field names in the reference. And the reference is not available from this function.

Parameters
fss

Definition at line 151 of file points_to_init_analysis.c.

152 {
153  // local name for the stub
154  string s = string_undefined;
155  string en = (string) entity_user_name(e);
156 
157  // FI: guarantee about *local* new name uniqueness?
158  if(formal_parameter_p(e)) {
159  // Naming for sinks of formal parameters: use their offsets
161  int off = formal_offset(f);
162  s = strdup(concatenate("_", en, fs,"_", int2a(off), NULL));
163  }
164  else if(top_level_entity_p(e) && !entity_stub_sink_p(e)) {
165  // FI: global_variable_p()
166  // Naming for sinks of global variables: use their offsets
167  int off = ram_offset(storage_ram(entity_storage(e)));
168  /* FI: I assume all unknown offsets defined in ri-util-local.h to
169  be strictly negative. */
170  if(off>=0)
171  s = strdup(concatenate("_", en, fs, "_", int2a(off), NULL));
172  else
173  /* FI: we could use a 0 as default offset for clarity? */
174  s = strdup(concatenate("_", en, fs, "_", NULL));
175  }
176  else if(static_global_variable_p(e)){ // "static int i;"
177  // Naming for sinks of static global variable: use their offsets
178  int off = ram_offset(storage_ram(entity_storage(e)));
179  s = strdup(concatenate("_", en, fs,"_", int2a(off), NULL));
180  }
181  else if(entity_stub_sink_p(e)) {
182  // Naming for sinks of stubs: repeat their last suffix
183  char *suffix = strrchr(en,'_');
184  s = strdup(concatenate( en, fs, suffix, NULL ));
185  }
186 
187  // FI: the stub entity already exists?
188 
189  // This is not OK in an interprocedural setting
190  //entity m = get_current_module_entity();
191  // entity m = entity_to_module_entity(e);
193 
194  //string formal_name = strdup(concatenate(get_current_module_name(),
195  // MODULE_SEP_STRING, s, NULL));
196  string formal_name = strdup(concatenate(entity_local_name(m),
197  MODULE_SEP_STRING, s, NULL));
198  entity stub = gen_find_entity(formal_name);
199  // FI: I expect here a pips_assert("The stub cannot exist",
200  // entity_undefined_p(stub));
201 
202  // If entity "stub" does not already exist, create it.
203  if(entity_undefined_p(stub)) {
206  if(type_undefined_p(entity_type(fa))) {
207  // entity a = module_to_heap_area(f);
209 
210  //ram r = make_ram(f, a, DYNAMIC_RAM_OFFSET, NIL);
213  // FI: DO we want to declare it abstract location?
215  //entity_kind(fa) = ENTITY_FORMAL_AREA;
217  }
218  stub = make_entity(formal_name,
219  copy_type(t),
222  (void) add_C_variable_to_area(fa, stub);
223 
224  AddEntityToDeclarations(stub, m);
225  }
226  else {
227  /* FI: we are in deep trouble because the stub entity has already
228  * been created... but we have no idea if it is or not the entity we
229  * wanted as it depends on field names in the reference. And the
230  * reference is not available from this function.
231  */
232  type st = entity_basic_concrete_type(stub);
233  if(array_pointer_type_equal_p(st, t)) {
234  // This may happen when evaluating conditions on demand because
235  // they are evaluated twice, once true and once false.
236  ;
237  }
238  else
239  // Should be an internal error...
240  pips_internal_error("Type incompatible request for a stub.\n");
241  }
242 
243  return stub;
244 }
storage make_storage_rom(void)
Definition: ri.c:2285
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
area make_area(intptr_t a1, list a2)
Definition: ri.c:98
type make_type(enum type_utype tag, void *val)
Definition: ri.c:2706
bool entity_stub_sink_p(entity e)
test if an entity is a stub sink for a formal parameter e.g.
#define FORMAL_AREA_LOCAL_NAME
Definition: naming-local.h:76
#define string_undefined
Definition: newgen_types.h:40
char * string
STRING.
Definition: newgen_types.h:39
#define UU
Definition: newgen_types.h:98
#define DYNAMIC_RAM_OFFSET
FI: I would have assumed that it is used for the stack area, but I must be wrong.....
@ ENTITY_FORMAL_AREA
@ ABSTRACT_LOCATION
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
bool static_global_variable_p(entity)
Is v a global variable declared local to a C file such "static int i;".
Definition: variable.c:1498
int add_C_variable_to_area(entity, entity)
Definition: variable.c:1381
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
@ is_value_unknown
Definition: ri.h:3035
#define type_undefined_p(x)
Definition: ri.h:2884
#define storage_ram(x)
Definition: ri.h:2521
@ is_type_area
Definition: ri.h:2899
#define entity_type(x)
Definition: ri.h:2792
#define ram_offset(x)
Definition: ri.h:2251
#define entity_initial(x)
Definition: ri.h:2796

References ABSTRACT_LOCATION, add_C_variable_to_area(), AddEntityToDeclarations(), array_pointer_type_equal_p(), concatenate(), copy_type(), DYNAMIC_RAM_OFFSET, entity_basic_concrete_type(), ENTITY_FORMAL_AREA, entity_initial, entity_kind, entity_local_name(), entity_module_name(), entity_storage, entity_stub_sink_p(), entity_type, entity_undefined_p, entity_user_name(), f(), FindOrCreateEntity(), FORMAL_AREA_LOCAL_NAME, formal_offset, formal_parameter_p(), gen_find_entity(), int2a(), is_type_area, is_value_unknown, make_area(), make_entity, make_ram(), make_storage_ram(), make_storage_rom(), make_type(), make_value(), make_value_unknown(), module_name_to_entity(), MODULE_SEP_STRING, NIL, pips_internal_error, ram_offset, static_global_variable_p(), storage_formal, storage_ram, strdup(), string_undefined, top_level_entity_p(), type_undefined_p, and UU.

Referenced by create_scalar_stub_sink_cell().

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

◆ create_stub_points_to()

points_to create_stub_points_to ( cell  c,
type unused_st   __attribute__(__unused__),
bool  exact_p 
)

points_to create_stub_points_to(cell c, bool exact_p)

To create the points-to arc "pt_to" between a cell "c" containing a constant path reference based on a formal parameter or a global variable or another stub on one hand, and another new points-to stub reference on the other.

Argument "exact_p" specifies the approximation of the generated points-to arc. It is overriden when NULL pointers are distinguished according to property POINTS_TO_NULL_POINTER_INITIALIZATION. This simplifies the semantics of the stub entities: they cannot represent/hide the NULL abstract cell.

The arc approximation itself is another issue as pointed out by Beatrice Creusillet because we may have an approximation on the source node, on the sink node or on the arc. Currently, an exact approximation seems to indicate that no approximation at all is made. This is issue is not currently solved (13 August 2012).

Assumption: the reference in source cell "c" is a constant memory path. So is the new reference hidden in the sink cell.

This function must be consistent with type compatibility checks used in points-to analysis, points_to_cell_types_compatibility(l, r).

The global sink name of the generated stub is a concatenation of the formal parameter, underscore, some number, and POINTS_TO_MODULE_NAME as module name.

The type of cell "c" and the type of the sink cell that is generated must fit in some complicated way:

  1. Do we consider types to be strict or do we allow pointer arithmetic, which implies that pointers to scalars or anything else in fact points to arrays? This is controlled by property POINTS_TO_STRICT_POINTER_TYPES.
  2. When the source is an array of pointers, do we add its dimensions to the type of the sink? Yes, to preserve the independence of independent cells (i.e. to be ready for a future version with descriptors, compatible with dependence testing).
  3. When the source is a really subscripted reference to an array of pointers, how do we generate the subscripts of the sink? Especially if the source is partially subscripted? We try to copy the subscript to preserve as much information as possible.
  4. Also, we have a choice: either point toward the first element of an implicit array or point towards the array itself. To be consistent with the interpretation of "p=a;" and "p=&a[0]", we chose to points towards the object itself. But Pass effects_with_points_to seems to expect pointers to the first array element. A normalization function could be used to switch from one convention to the other. The current idea is that, as much as possible, points-to "c1->c2" implies that "c1==&c2;" holds. So 0 subscript are added to fill the last dimensions of the sink reference.

Here, we needs lots of examples with constant memory path references to prepare a precise specification of the desired function. Let c stands for the reference hidden in cell "c":

  • assignment13.c: "c=_t2_2_2[0][ip2];": here we have an array of structs containing a pointer field. Beatrice would like us to infer _t2_2_2[*][ip2] -> _t2_2_2_2[*]... Imagine the general case with structs with arrays of structs with... We may also want an arc _t2_2_2[*][ip2] -> NULL (see property POINTS_TO_NULL_POINTER_INITIALIZATION), or even an arc _t2_2_2[*][ip2] -> UNDEFINED (not implemented because about useless since parameters are passed by value). We may also want: _t2_2_2[*][ip2] -> _t2_2_2_2[*][0]
  • "void foo(int *p) c=p;": depending on property on strict typing, POINTS_TO_STRICT_POINTER_TYPES, we want either p -> _p_1 or p -> _p_1[0]
  • "void foo(int * pa[10]) {int * c=pa[0];}": pa[*] -> NULL, pa[*] -> _pa_1[*] but c->_pa_1[0]
  • ptr_to_array01.c: "int ptr_to_array01(int * (*p)[10]) {int a; (*p)[3] = &a;}" p->_p_1, p_1[3] -> a

The cell "c" is not embedded in the generated points-to "pt_to". A copy is allocated. The output has no sharing with the input parameters.

&& vd==0

You may have a pointer or an unbounded array for source_t...

Take care of void *

Update sink_t to take into account all the dimensions existing in the source

stub_t is same as sink_t, but add a dimension array arithmetic

Definition at line 580 of file points_to_init_analysis.c.

584 {
585  cell source_cell = copy_cell(c);
586  reference source_r = cell_any_reference(source_cell);
587  // FI: The field disambiguator "fs" is derived from source_r
588  string fs = reference_to_field_disambiguator(source_r);
589  entity v = reference_variable(source_r);
590  list source_sl = reference_indices(source_r); // subscript list
591  // The indices of a points-to reference may include fields as well as
592  // usual array subscripts
593  list sl = gen_full_copy_list(reference_indices(source_r));
594  //bool to_be_freed;
595  //type c_t = points_to_cell_to_type(c, &to_be_freed);
596  //type source_t = compute_basic_concrete_type(c_t);
598  cell sink_cell = cell_undefined;
599  bool e_exact_p = true;
600 
603  pips_assert("fopen is fully defined", !type_undefined_p(entity_type(f)));
604  entity io_files = MakeIoFileArray(f);
605  int n = ENTITY_STDIN_P(v) ? STDIN_FILENO :
608  sink_cell = make_cell_reference(sr);
609  }
610  else if(type_variable_p(source_t)) {
611  bool strict_p = get_bool_property("POINTS_TO_STRICT_POINTER_TYPES");
612  //variable source_tv = type_variable(source_t);
613  //list source_dl = variable_dimensions(source_tv);
614  //int source_vd = (int) gen_length(source_dl); // FI: seems useless
615  int source_cd = points_to_indices_to_array_index_number(source_sl);
616 
617  if(source_cd==0 /* && vd==0*/ ) {
618  /* You may have a pointer or an unbounded array for source_t... */
619  type sink_t = C_type_to_pointed_type(source_t);
620  /* Take care of void * */
621  type r_sink_t = type_void_p(sink_t)?
623  : copy_type(sink_t);
624  type stub_t = (strict_p || !type_variable_p(r_sink_t))?
625  copy_type(r_sink_t) : type_to_array_type(r_sink_t);
626  free_type(r_sink_t);
627  sink_cell = create_scalar_stub_sink_cell(v, stub_t, sink_t, 0, NIL, fs);
628  e_exact_p = exact_p;
629  free_type(sink_t);
630  }
631  else if(source_cd>0) {
632  // If called for a formal parameter, the reference may not
633  // contain indices although we are dealing with an array...
634  if(ENDP(sl)) {
635  sl = make_unbounded_dimensions(source_cd);
636  }
637  else {
638  // In case subscript indices have non constant values, replace them
639  // with unbounded expressions
641  }
642  // dimensions to be added to the dimensions of "sink_t"
643  list ndl = make_unbounded_dimensions(source_cd);
644  type sink_t = copy_type(type_to_pointed_type(source_t));
645  if(type_void_p(sink_t)) {
646  free_type(sink_t);
648  }
649  /* Update sink_t to take into account all the dimensions
650  existing in the source */
651  pips_assert("type_variable_p(sink_t)", type_variable_p(sink_t));
652  variable nstv = type_variable(sink_t);
654 
655  /* stub_t is same as sink_t, but add a dimension array arithmetic */
656  type stub_t = strict_p ? copy_type(sink_t) : type_to_array_type(sink_t);
657 
658  sink_cell = create_scalar_stub_sink_cell(v, stub_t, sink_t, source_cd, sl, fs);
659  // FI: this should be performed by the previous function
660  // points_to_cell_add_unbounded_subscripts(sink_cell);
661  e_exact_p = false;
662  }
663  }
664  else if(type_functional_p(source_t)) {
665  pips_internal_error("Unexpected case.\n");
666  // sink_cell = create_scalar_stub_sink_cell(v, copy_type(st), st, 0);
667  e_exact_p = true;
668  }
669  else
670  pips_internal_error("Unexpected case.\n");
671 
672  points_to_cell_types_compatibility(source_cell, sink_cell);
673  approximation rel = e_exact_p? make_approximation_exact():
675  points_to pt_to = make_points_to(source_cell, sink_cell, rel,
677  pointer_index ++; // FI: is not used for formal parameters, is this the right place for the increment
678 
679  //if(to_be_freed) free_type(c_t);
680 
681  return pt_to;
682 }
basic make_basic_overloaded(void)
Definition: ri.c:167
entity MakeIoFileArray(entity f)
This array is pointed by FILE * pointers returned or used by fopen, fclose,...
Definition: bootstrap.c:5705
void points_to_cell_types_compatibility(cell, cell)
Make sure that cell l can points towards cell r.
Definition: type.c:985
#define cell_undefined
Definition: effects.h:430
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
#define STDOUT_FILENO
Definition: unistd.in.h:211
#define STDERR_FILENO
Definition: unistd.in.h:214
#define STDIN_FILENO
NetBSD 5.0 mis-defines NULL.
Definition: unistd.in.h:208
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
int points_to_indices_to_array_index_number(list sl)
Count the number of array indices and ignore the field subscripts.
list points_to_indices_to_subscript_indices(list ptsl)
Generate a new subscript list.
string reference_to_field_disambiguator(reference r)
Build an ASCII string to disambiguate the different field paths that may exist in similar references.
cell create_scalar_stub_sink_cell(entity v, type st, type pt, int d, list sl, string fs)
Create a stub entity "se" for entity "v" with type "t" and return a cell based on a reference to the ...
#define FOPEN_FUNCTION_NAME
#define ENTITY_STDIN_P(e)
#define DEFAULT_CHARACTER_TYPE_SIZE
Default type sizes.
#define ENTITY_STDERR_P(e)
#define ENTITY_STDOUT_P(e)
list make_unbounded_dimensions(int)
Minimal information to build a d-dimensional array type.
Definition: type.c:5752
type C_type_to_pointed_type(type)
returns a copy of t if t is not a pointer type, and the pointed type if t is a pointer type or.
Definition: type.c:5288
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
type make_scalar_integer_type(_int)
Definition: type.c:712

References C_type_to_pointed_type(), cell_any_reference(), cell_undefined, CONS, copy_cell(), copy_type(), create_scalar_stub_sink_cell(), DEFAULT_CHARACTER_TYPE_SIZE, ENDP, ENTITY_STDERR_P, ENTITY_STDIN_P, ENTITY_STDOUT_P, entity_type, EXPRESSION, f(), FindOrCreateEntity(), FOPEN_FUNCTION_NAME, free_type(), gen_full_copy_list(), gen_nconc(), get_bool_property(), int_to_expression(), make_approximation_exact(), make_approximation_may(), make_basic_overloaded(), make_cell_reference(), make_descriptor_none(), make_points_to(), make_reference(), make_scalar_integer_type(), make_type_variable(), make_unbounded_dimensions(), make_variable(), MakeIoFileArray(), NIL, pips_assert, pips_internal_error, pointer_index, points_to_cell_to_concrete_type(), points_to_cell_types_compatibility(), points_to_indices_to_array_index_number(), points_to_indices_to_subscript_indices(), reference_indices, reference_to_field_disambiguator(), reference_variable, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, TOP_LEVEL_MODULE_NAME, type_functional_p, type_to_array_type(), type_to_pointed_type(), type_undefined_p, type_variable, type_variable_p, type_void_p, and variable_dimensions.

Referenced by array_formal_parameter_to_stub_points_to(), create_advanced_stub_points_to(), derived_formal_parameter_to_stub_points_to(), pointer_formal_parameter_to_stub_points_to(), and typedef_formal_parameter_to_stub_points_to().

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

◆ derived_formal_parameter_to_stub_points_to()

set derived_formal_parameter_to_stub_points_to ( type  pt,
cell  c 
)

Input : a formal parameter which has a derived type (FI, I guess).

output : a set of points-to where sinks are stub points-to.

FI: a lot of rewrite needed to simplify. Also, do not forget that NULL maybe the received value.

maybe should be removed if we have already called ultimate type in formal_points_to_parameter()

We ignore dimensions for the time being, descriptors are not implemented yet...Amira Mensi

ultimate_type() returns a wrong type for arrays. For example for type int*[10] it returns int*[10] instead of int[10].

In fact, there should be a FOREACH to scan all elements of l_ef

free the spine

Parameters
ptt

Definition at line 952 of file points_to_init_analysis.c.

953 {
956  bool exact_p = !get_bool_property("POINTS_TO_NULL_POINTER_INITIALIZATION");
961  /* maybe should be removed if we have already called ultimate type
962  * in formal_points_to_parameter() */
963 
964  type upt = type_to_pointed_type(pt);
965  r = cell_any_reference(c);
966  e = reference_variable(r);
967 
968  if(type_variable_p(upt)){
969  if(array_entity_p(e)){
970  /* We ignore dimensions for the time being, descriptors are not
971  * implemented yet...Amira Mensi*/
972  ;
973  /* ultimate_type() returns a wrong type for arrays. For
974  * example for type int*[10] it returns int*[10] instead of int[10]. */
975  }
976  else {
977  basic fpb = variable_basic(type_variable(upt));
978  if( basic_derived_p(fpb)) {
981  if(type_variable_p(t)){
983  if(basic_derived_p(vb)){
984  entity ed = basic_derived(vb);
985  type et = entity_type(ed);
986  if(type_struct_p(et)){
987  list l1 = type_struct(et);
988  FOREACH(ENTITY, i, l1){
989 
991  if(expression_pointer_p(ef)){
992  type ent_type = entity_type(i);
993  fpb = variable_basic(type_variable(ent_type));
995  ex,
996  ef);
999  list l_ef = NIL;
1001  true);
1002  ef = EFFECT(CAR(l_ef)); /* In fact, there should be a FOREACH to scan all elements of l_ef */
1003  gen_free_list(l_ef); /* free the spine */
1004 
1005  reference source_ref = effect_any_reference(ef);
1006  effects_free(l1);
1008  type p_ent_type = compute_basic_concrete_type(type_to_pointed_type(ent_type));
1009  cell source_cell = make_cell_reference(source_ref);
1010  pt_to = create_stub_points_to(source_cell, p_ent_type, exact_p);
1011  pt_in = set_add_element(pt_in, pt_in,
1012  (void*) pt_to );
1013  }
1014 
1015  }
1016  }
1017  }
1018  }
1019  }
1020  }
1021  }
1022 
1023  return pt_in;
1024 
1025 
1026 }
list generic_proper_effects_of_complex_address_expression(expression, list *, int)
void effects_free(list)
void generic_effects_reset_all_methods(void)
void set_methods_for_proper_simple_effects(void)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_undefined
Definition: effects.h:614
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define FIELD_OPERATOR_NAME
Definition: ri-util-local.h:91
bool array_entity_p(entity e)
Definition: entity.c:793
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
bool expression_pointer_p(expression e)
we get the type of the expression by calling expression_to_type() which allocates a new one.
Definition: expression.c:506
type ultimate_type(type)
Definition: type.c:3466
type compute_basic_concrete_type(type)
computes a new type which is the basic concrete type of the input type (this new type is not stored i...
Definition: type.c:3556
#define type_struct(x)
Definition: ri.h:2964
#define type_struct_p(x)
Definition: ri.h:2962
#define basic_derived(x)
Definition: ri.h:640
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define basic_derived_p(x)
Definition: ri.h:638
#define entity_undefined
Definition: ri.h:2761

References array_entity_p(), basic_derived, basic_derived_p, CAR, cell_any_reference(), compute_basic_concrete_type(), create_stub_points_to(), EFFECT, effect_any_reference, effect_undefined, effects_free(), ENTITY, entity_intrinsic(), entity_to_expression(), entity_type, entity_undefined, expression_pointer_p(), FIELD_OPERATOR_NAME, FOREACH, gen_free_list(), generic_effects_reset_all_methods(), generic_proper_effects_of_complex_address_expression(), get_bool_property(), make_cell_reference(), MakeBinaryCall(), NIL, points_to_equal_p(), points_to_rank(), points_to_undefined, reference_undefined, reference_variable, set_add_element(), set_generic_make(), set_methods_for_proper_simple_effects(), set_private, type_struct, type_struct_p, type_to_pointed_type(), type_variable, type_variable_p, ultimate_type(), and variable_basic.

Referenced by formal_points_to_parameter().

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

◆ formal_points_to_parameter()

set formal_points_to_parameter ( cell  c)

We want a recursive descent on the type of the formal parameter, once we found a pointer type we beguin a recursive descent until founding a basic case.

Then we beguin the ascent and the creation gradually of the points_to_stub by calling pointer_formal_parameter_to_stub_points_to().

FI->AM: as I would rather work on-demand, this function should be useless. I fixed it nevertheless because it seems better for EffectsWithPointsTo, which does not seem to allocate the new points-to stubs it needs.

fpt = entity_basic_concrete_type(e);

We ignor dimensions for the time being, descriptors are not implemented yet...Amira Mensi

what about storage

Definition at line 85 of file points_to_init_analysis.c.

86 {
88  type fpt = type_undefined;
92 
93  r = cell_to_reference(c);
94  bool to_be_freed = false;
95  /* fpt = entity_basic_concrete_type(e); */
96  fpt = cell_reference_to_type(r,&to_be_freed);
97  if(type_variable_p(fpt)){
98  /* We ignor dimensions for the time being, descriptors are not
99  * implemented yet...Amira Mensi*/
100  basic fpb = variable_basic(type_variable(fpt));
101  if(array_type_p(fpt)) {
102  pt_in = set_union(pt_in, pt_in, array_formal_parameter_to_stub_points_to(fpt,c));
103  }
104  else {
105  switch(basic_tag(fpb)){
106  case is_basic_int:
107  break;
108  case is_basic_float:
109  break;
110  case is_basic_logical:
111  break;
112  case is_basic_overloaded:
113  break;
114  case is_basic_complex:
115  break;
116  case is_basic_pointer:{
117  pt_in = set_union(pt_in, pt_in, pointer_formal_parameter_to_stub_points_to(fpt,c));
118  /* what about storage*/
119  break;
120  }
121  case is_basic_derived:{
122  pt_in = set_union(pt_in, pt_in, derived_formal_parameter_to_stub_points_to(fpt,c));
123  break;
124  }
125  case is_basic_string:
126  break;
127  case is_basic_typedef:{
128  pt_in = set_union(pt_in, pt_in, typedef_formal_parameter_to_stub_points_to(fpt,c));
129  break;
130  }
131  case is_basic_bit:
132  break;
133  default: pips_internal_error("unexpected tag %d", basic_tag(fpb));
134  }
135  }
136  }
137  if (to_be_freed) free_type(fpt);
138  return pt_in;
139 
140 }
reference cell_to_reference(cell)
FI: probably to be moved elsewhere in ri-util.
Definition: effects.c:1326
type cell_reference_to_type(reference, bool *)
computes the type of a cell reference representing a memory access path.
Definition: type.c:466
set set_union(set, const set, const set)
Definition: set.c:211
set array_formal_parameter_to_stub_points_to(type t, cell c)
Type "t" is supposed to be a concrete type.
set pointer_formal_parameter_to_stub_points_to(type pt, cell c)
Input : a formal parameter which is a pointer and its type.
set derived_formal_parameter_to_stub_points_to(type pt, cell c)
Input : a formal parameter which has a derived type (FI, I guess).
set typedef_formal_parameter_to_stub_points_to(type pt, cell c)
Input : a formal parameter which is a typedef.
@ is_basic_derived
Definition: ri.h:579
@ is_basic_string
Definition: ri.h:576
@ is_basic_float
Definition: ri.h:572
@ is_basic_bit
Definition: ri.h:577
@ is_basic_pointer
Definition: ri.h:578
@ is_basic_overloaded
Definition: ri.h:574
@ is_basic_int
Definition: ri.h:571
@ is_basic_logical
Definition: ri.h:573
@ is_basic_typedef
Definition: ri.h:580
@ is_basic_complex
Definition: ri.h:575
#define basic_tag(x)
Definition: ri.h:613

References array_formal_parameter_to_stub_points_to(), array_type_p(), basic_tag, cell_reference_to_type(), cell_to_reference(), derived_formal_parameter_to_stub_points_to(), free_type(), is_basic_bit, is_basic_complex, is_basic_derived, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_pointer, is_basic_string, is_basic_typedef, pips_internal_error, pointer_formal_parameter_to_stub_points_to(), points_to_equal_p(), points_to_rank(), reference_undefined, set_generic_make(), set_private, set_union(), type_undefined, type_variable, type_variable_p, typedef_formal_parameter_to_stub_points_to(), and variable_basic.

Referenced by init_points_to_analysis().

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

◆ pointer_formal_parameter_to_stub_points_to()

set pointer_formal_parameter_to_stub_points_to ( type  pt,
cell  c 
)

Input : a formal parameter which is a pointer and its type.

Output : a set of points-to where sinks are stub points-to. we descent recursively until reaching a basic type, then we call create_stub_points_to()to generate the adequate points-to.

FI: I do not know if I want to keep using this function because stubs are not created on demand and because some are certainly not useful for the points-to analysis. But they may be useful for client analysis... However, client analyses will have to create more such stubs...

maybe should be removed if we have already called ultimate type in formal_points_to_parameter()

The pointer may be NULL or undefined. We neglect undefined/nowhere

The pointer may points towards another object (or set of object)

Recursive descent for pointers: the new sink becomes the new source... FI: I do not think this is useful because they will be created on demand...

what about storage

Create a target of unknown type

make_type_unknown()

Parameters
ptt

Definition at line 810 of file points_to_init_analysis.c.

811 {
816  /* maybe should be removed if we have already called ultimate type
817  * in formal_points_to_parameter() */
818 
819  /* The pointer may be NULL or undefined. We neglect undefined/nowhere */
820  // AM: Get the property POINTS_TO_NULL_POINTER_INITIALIZATION
821  bool null_initialization_p = get_bool_property("POINTS_TO_NULL_POINTER_INITIALIZATION");
822  if(null_initialization_p) {
823  cell nc = copy_cell(c);
825  points_to npt = make_points_to(nc, null_c,
828  pt_in = add_arc_to_simple_pt_map(npt, pt_in);
829  }
830 
831  /* The pointer may points towards another object (or set of object) */
832  type upt = type_to_pointed_type(pt);
833  if( type_variable_p(upt) ){
834  basic fpb = variable_basic(type_variable(upt));
835  if( array_type_p(upt) ){
837  !null_initialization_p);
838  pt_in = set_add_element(pt_in, pt_in,
839  (void*) pt_to );
840  }
841  else {
842  switch(basic_tag(fpb)){
843  case is_basic_int:{
844  // type st = type_undefined; // sink type
845  // pt_to = create_advanced_stub_points_to(c, upt, !null_initialization_p);
846  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
847  pt_in = set_add_element(pt_in, pt_in,
848  (void*) pt_to );
849  break;
850  }
851  case is_basic_float:{
852  //pt_to = create_advanced_stub_points_to(c, upt, !null_initialization_p);
853  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
854  pt_in = set_add_element(pt_in, pt_in,
855  (void*) pt_to );
856  break;
857  }
858  case is_basic_logical:{
859  //pt_to = create_advanced_stub_points_to(c, upt, !null_initialization_p);
860  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
861  pt_in = set_add_element(pt_in, pt_in,
862  (void*) pt_to );
863  break;
864  }
865  case is_basic_overloaded:{
866  // FI: Oops, what are we doing here?
867  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
868  pt_in = set_add_element(pt_in, pt_in,
869  (void*) pt_to );
870  break;
871  }
872  case is_basic_complex:{
873  //pt_to = create_advanced_stub_points_to(c, upt, !null_initialization_p);
874  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
875  pt_in = set_add_element(pt_in, pt_in,
876  (void*) pt_to );
877  break;
878  }
879  case is_basic_pointer:{
880  //pt_to = create_advanced_stub_points_to(c, upt, !null_initialization_p);
881  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
882  pt_in = set_add_element(pt_in, pt_in,
883  (void*) pt_to );
884  cell sink = points_to_sink(pt_to);
885  if(false) {
886  /* Recursive descent for pointers: the new sink becomes the
887  new source... FI: I do not think this is useful because
888  they will be created on demand... */
890  pt_in = set_union(pt_in, pt_in,tmp);
891  set_free(tmp);
892  }
893  /* what about storage*/
894  break;
895  }
896  case is_basic_derived:{
897  //pt_to = create_advanced_stub_points_to(c, upt, !null_initialization_p);
898  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
899  pt_in = set_add_element(pt_in, pt_in,
900  (void*) pt_to );
901  break;
902  }
903  case is_basic_bit:
904  pips_internal_error("Not implemented.\n");
905  break;
906  case is_basic_string:{
907  // FI: I'm not too sure about what to do for strings...
908  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
909  pt_in = set_add_element(pt_in, pt_in,
910  (void*) pt_to );
911  break;
912  }
913  case is_basic_typedef:{
914  //pt_to = create_advanced_stub_points_to(c, upt, !null_initialization_p);
915  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
916  pt_in = set_add_element(pt_in, pt_in,
917  (void*) pt_to );
918  break;
919  }
920  default: pips_internal_error("unexpected tag %d", basic_tag(fpb));
921  break;
922  }
923  }
924  }
925  else if(type_functional_p(upt)) {
926  pt_to = create_stub_points_to(c, upt, !null_initialization_p);
927  add_arc_to_simple_pt_map(pt_to, pt_in);
928 }
929  else if(type_void_p(upt)) {
930  /* Create a target of unknown type */
931  pt_to = create_stub_points_to(c, upt/* make_type_unknown() */,
932  !null_initialization_p);
933  pt_in = set_add_element(pt_in, pt_in, (void*) pt_to );
934  }
935  else
936  //we don't know how to handle other types
937  pips_internal_error("Unexpected type");
938 
939  return pt_in;
940 
941 
942 }
#define add_arc_to_simple_pt_map(a, s)
cell make_null_pointer_value_cell(void)
void set_free(set)
Definition: set.c:332
points_to create_pointer_to_array_stub_points_to(cell c, type t, bool exact_p)
To create the points-to stub associated to the formal parameter, the sink name is a concatenation of ...
#define points_to_sink(x)

References add_arc_to_simple_pt_map, array_type_p(), basic_tag, copy_cell(), create_pointer_to_array_stub_points_to(), create_stub_points_to(), get_bool_property(), is_basic_bit, is_basic_complex, is_basic_derived, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_pointer, is_basic_string, is_basic_typedef, make_approximation_may(), make_descriptor_none(), make_null_pointer_value_cell(), make_points_to(), pips_internal_error, pointer_formal_parameter_to_stub_points_to(), points_to_equal_p(), points_to_rank(), points_to_sink, points_to_undefined, set_add_element(), set_free(), set_generic_make(), set_private, set_union(), type_functional_p, type_to_pointed_type(), type_variable, type_variable_p, type_void_p, and variable_basic.

Referenced by formal_points_to_parameter(), and pointer_formal_parameter_to_stub_points_to().

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

◆ points_to_backward_translation()

void points_to_backward_translation ( void  )

Definition at line 71 of file points_to_init_analysis.c.

72 {
73 }

◆ points_to_forward_translation()

void points_to_forward_translation ( void  )

-----------------------------—Interprocedural Points-to Analysis--------------------—

points_to_init_analysis.c

This package computes the points-to interprocedurally.

See Chapter ? in Amira Mensi's PhD dissertation.

Definition at line 66 of file points_to_init_analysis.c.

67 {
68 
69 }

◆ points_to_indices_to_array_index_number()

int points_to_indices_to_array_index_number ( list  sl)

Count the number of array indices and ignore the field subscripts.

Parameters
sll

Definition at line 384 of file points_to_init_analysis.c.

385 {
386  int c = 0;
387  FOREACH(EXPRESSION, s, sl) {
388  if(!expression_reference_p(s))
389  c++;
390  }
391  return c;
392 }
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528

References EXPRESSION, expression_reference_p(), and FOREACH.

Referenced by create_stub_points_to().

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

◆ points_to_indices_to_subscript_indices()

list points_to_indices_to_subscript_indices ( list  ptsl)

Generate a new subscript list.

References to fields are ignored, constant and unbounded expressions are preserved, non-constant expressions are replaced by unbounded expressions.

Parameters
ptsltsl

Definition at line 425 of file points_to_init_analysis.c.

426 {
427  list csl = NIL;
428  list sl = NIL;
429  for(csl = ptsl; !ENDP(csl); POP(csl)) {
430  expression se = EXPRESSION(CAR(csl));
431  // FI: how many different kinds of expressions do we have?
432  // This dichotomy between references and calls may be too simple
433  if(!expression_reference_p(se)) {
434  if(!unbounded_expression_p(se)) {
436  sl = CONS(EXPRESSION, copy_expression(se), sl);
437  else
438  // do not propagate store-dependent information
440  }
441  else { // copy the unbounded expression
442  sl = CONS(EXPRESSION, copy_expression(se), sl);
443  }
444  }
445  else {
447  entity v = reference_variable(r);
448  if(entity_field_p(v))
449  ; // ignore fields
450  else
451  // do not propagate store-dependent information
453  }
454  }
455  sl = gen_nreverse(sl);
456  return sl;
457 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
bool extended_integer_constant_expression_p(expression e)
More extensive than next function.
Definition: expression.c:858
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832

References CAR, CONS, copy_expression(), ENDP, entity_field_p(), EXPRESSION, expression_reference(), expression_reference_p(), extended_integer_constant_expression_p(), gen_nreverse(), make_unbounded_expression(), NIL, POP, reference_variable, and unbounded_expression_p().

Referenced by create_stub_points_to().

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

◆ points_to_indices_to_unbounded_indices()

void points_to_indices_to_unbounded_indices ( list  sl)

FI: probably a duplicate...

Parameters
sll

Definition at line 395 of file points_to_init_analysis.c.

396 {
397  list csl = NIL;
398  for (csl = sl; !ENDP(csl); POP(csl)) {
399  expression se = EXPRESSION(CAR(csl));
400  if (!expression_reference_p(se)) {
401  if (unbounded_expression_p(se))
402  ;
403  else if (expression_is_constant_p(se))
404  ;
405  else {
406  free_expression(se);
408  }
409  }
410  else {
412  entity v = reference_variable(r);
413  if(!entity_field_p(v))
414  free_expression(se);
416  }
417  }
418  return; // Useful for gdb?
419 }
void free_expression(expression p)
Definition: ri.c:853
bool expression_is_constant_p(expression e)
BEGIN_EOLE.
Definition: constant.c:666
#define EXPRESSION_(x)
Definition: ri.h:1220

References CAR, ENDP, entity_field_p(), EXPRESSION, EXPRESSION_, expression_is_constant_p(), expression_reference(), expression_reference_p(), free_expression(), make_unbounded_expression(), NIL, POP, reference_variable, and unbounded_expression_p().

+ Here is the call graph for this function:

◆ reference_to_field_disambiguator()

string reference_to_field_disambiguator ( reference  r)

Build an ASCII string to disambiguate the different field paths that may exist in similar references.

If the variable referenced by "r" is not a struct, returns the empty string.

If it is a struct, derive a string that is unique to a particular combination of fields and subfields.

Definition at line 468 of file points_to_init_analysis.c.

469 {
470  string fs = string_undefined;
471  string ofs = string_undefined;
472  list sl = reference_indices(r);
473  FOREACH(EXPRESSION, s, sl) {
474  if(expression_reference_p(s)) {
476  if(entity_field_p(f)) {
477  int n = entity_field_rank(f);
478  if(string_undefined_p(fs))
479  asprintf(&fs, "_%d_", n);
480  else {
481  ofs = fs;
482  asprintf(&fs, "%s%d_", ofs, n);
483  free(ofs);
484  }
485  }
486  }
487  }
488  if(string_undefined_p(fs))
489  fs = strdup("");
490  return fs;
491 }
void free(void *)
#define asprintf
Definition: misc-local.h:225
#define string_undefined_p(s)
Definition: newgen_types.h:41
int entity_field_rank(entity f)
f is a field of a structure or of an union: what is its rank?
Definition: entity.c:940

References asprintf, entity_field_p(), entity_field_rank(), EXPRESSION, expression_reference(), expression_reference_p(), f(), FOREACH, free(), reference_indices, reference_variable, strdup(), string_undefined, and string_undefined_p.

Referenced by create_stub_points_to().

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

◆ typedef_formal_parameter_to_stub_points_to()

set typedef_formal_parameter_to_stub_points_to ( type  pt,
cell  c 
)

Input : a formal parameter which is a typedef.

FI: a formal parameter cannot be a typedef, but it can be typed with a typedefined type.

maybe should be removed if we have already called ultimate type in formal_points_to_parameter()

We ignor dimensions for the being, descriptors are not implemented yet...Amira Mensi

ultimate_type() returns a wrong type for arrays. For example for type int*[10] it returns int*[10] instead of int[10].

l = points_to_init_derived(e, e2);

In fact, there should be a FOREACH to scan all elements of l_ef

free the spine

Parameters
ptt

Definition at line 1033 of file points_to_init_analysis.c.

1034 {
1040  points_to_rank);
1041  bool exact_p = !get_bool_property("POINTS_TO_NULL_POINTER_INITIALIZATION");
1042 
1043  /* maybe should be removed if we have already called ultimate type
1044  * in formal_points_to_parameter() */
1045 
1046  type upt = type_to_pointed_type(pt);
1047  r = cell_any_reference(c);
1048  e = reference_variable(r);
1049 
1050  if(type_variable_p(upt)){
1051  if(array_entity_p(e)){
1052  /* We ignor dimensions for the being, descriptors are not
1053  * implemented yet...Amira Mensi*/
1054  ;
1055  /* ultimate_type() returns a wrong type for arrays. For
1056  * example for type int*[10] it returns int*[10] instead of int[10]. */
1057  }
1058  else {
1059  basic fpb = variable_basic(type_variable(upt));
1060  if(basic_typedef_p(fpb)){
1061  entity e1 = basic_typedef(fpb);
1062  type t1 = entity_type(e1);
1063  if(entity_variable_p(e1)){
1065  if(basic_derived_p(b2)){
1066  entity e2 = basic_derived(b2);
1067  /* l = points_to_init_derived(e, e2); */
1068  type t = entity_type(e2);
1070  if(type_struct_p(t)){
1071  list l1 = type_struct(t);
1072  FOREACH(ENTITY, i, l1){
1074  if(expression_pointer_p(ef)){
1075  type ent_type = entity_type(i);
1077  ex,
1078  ef);
1080  effect ef = effect_undefined;
1081  list l_ef = NIL;
1083  true);
1084  ef = EFFECT(CAR(l_ef)); /* In fact, there should be a FOREACH to scan all elements of l_ef */
1085  gen_free_list(l_ef); /* free the spine */
1086 
1087  reference source_ref = effect_any_reference(ef);
1088  effects_free(l1);
1090  cell source_cell = make_cell_reference(source_ref);
1091  pt_to = create_stub_points_to(source_cell, ent_type, exact_p);
1092  pt_in = set_add_element(pt_in, pt_in,
1093  (void*) pt_to );
1094  }
1095  }
1096  }
1097  }
1098  }
1099  }
1100  }
1101  }
1102 
1103  return pt_in;
1104 }
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
#define basic_typedef_p(x)
Definition: ri.h:641
#define basic_typedef(x)
Definition: ri.h:643
Value b2
Definition: sc_gram.c:105

References array_entity_p(), b2, basic_derived, basic_derived_p, basic_typedef, basic_typedef_p, CAR, cell_any_reference(), create_stub_points_to(), EFFECT, effect_any_reference, effect_undefined, effects_free(), ENTITY, entity_intrinsic(), entity_to_expression(), entity_type, entity_undefined, entity_variable_p, expression_pointer_p(), FIELD_OPERATOR_NAME, FOREACH, gen_free_list(), generic_effects_reset_all_methods(), generic_proper_effects_of_complex_address_expression(), get_bool_property(), make_cell_reference(), MakeBinaryCall(), NIL, points_to_equal_p(), points_to_rank(), points_to_undefined, reference_undefined, reference_variable, set_add_element(), set_generic_make(), set_methods_for_proper_simple_effects(), set_private, type_struct, type_struct_p, type_to_pointed_type(), type_variable, type_variable_p, and variable_basic.

Referenced by formal_points_to_parameter().

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

Variable Documentation

◆ pointer_index

int pointer_index = 1
static