PIPS
dereferencing.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include "genC.h"
#include "linear.h"
#include "ri-util.h"
#include "effects-util.h"
#include "misc.h"
#include "properties.h"
#include "ri.h"
#include "prettyprint.h"
#include "effects.h"
#include "transformer.h"
#include "semantics.h"
#include "points-to.h"
+ Include dependency graph for dereferencing.c:

Go to the source code of this file.

Functions

pt_map dereferencing_subscript_to_points_to (subscript sub, pt_map in)
 FI: As usual in dereferencing.c, it is not clear that this piece of code has not been implemented somewhere else because of the early restriction to pointer type only expressions. More...
 
pt_map dereferencing_to_points_to (expression p, pt_map in)
 Make sure that expression p can be dereferenced in points-to graph "in". More...
 
bool pointer_points_to_reference_p (reference r __attribute__((unused)))
 see if a points_to_reference includes a pointer dereferencing: this is impossible if the points-to reference is consistent. More...
 
void pointer_reference_dereferencing_to_points_to (reference r, pt_map in)
 
pt_map reference_dereferencing_to_points_to (reference r, pt_map in, bool nowhere_dereferencing_p, bool null_dereferencing_p)
 Can we execute the reference r in points-to context "in" without segfaulting? More...
 
bool expression_to_points_to_cell_p (expression e)
 Can expression e be reduced to a reference, without requiring an evaluation? More...
 
list dereferencing_to_sinks (expression a, pt_map in, bool eval_p)
 Returns "sinks", the list of cells pointed to by expression "a" according to points-to graph "in". More...
 

Function Documentation

◆ dereferencing_subscript_to_points_to()

pt_map dereferencing_subscript_to_points_to ( subscript  sub,
pt_map  in 
)

FI: As usual in dereferencing.c, it is not clear that this piece of code has not been implemented somewhere else because of the early restriction to pointer type only expressions.

dereferencing.c

But all pointer values must be generated, whether they point to pointers or anything else.

This piece of code is designed to handle pointer19.c, and hence pointer14.c, where arrays of pointers toward arrays of pointers are used.

It generates too many arcs, useless arcs, when the subscript list is broken down into many subscript constructs by PIPS C parser. This shows in Pointers/pointer14, 15 and 19.

a cannot evaluate to null or undefined

FI: we may need a special case for stubs...

We have to take "sel" into account since only the base of the target array is pointed to.

We have to bother with the source if it is an array, not if it is simply a pointer dereferenced by some subscripts as in dereferencing18.c.

Look for points-to arcs that must be duplicated using the subscripts as offsets

We must generate a new source with the offset defined by sel, and a new sink, with or without a an offset

Update the source cell

Is the source cell already known in the points-to relation?

Update the sink cell if necessary

Build the new points-to arc

Do not update set "in" while you are enumerating its elements

Update sets "in" with the new arcs. The arc must pre-exist the reference for the effects to be able to translate a non-constant effect. Thus, it should pre-exist the call site.

FI: I am not sure this is useful...

Parameters
subub
inn

Definition at line 71 of file dereferencing.c.

72 {
73  expression a = subscript_array(sub);
74  type at = expression_to_type(a);
75  type apt = type_to_pointed_type(at);
76  list sel = subscript_indices(sub);
77  /* a cannot evaluate to null or undefined */
78  /* FI: we may need a special case for stubs... */
79  in = dereferencing_to_points_to(a, in);
80  /* We have to take "sel" into account since only the base of the
81  target array is pointed to. */
82  list source_l = expression_to_points_to_sources(a, in);
83  list n_arc_l = NIL;
84 
85  FOREACH(CELL, source, source_l) {
86  /* We have to bother with the source if it is an array, not if it
87  is simply a pointer dereferenced by some subscripts as in
88  dereferencing18.c. */
89  reference source_r = cell_any_reference(source);
90  entity source_v = reference_variable(source_r);
91  type source_v_t = entity_basic_concrete_type(source_v);
92 
93  if(array_type_p(source_v_t)) {
94  /* Look for points-to arcs that must be duplicated using the
95  subscripts as offsets */
97  cell pt_source = points_to_source(pt);
98  //if(points_to_cell_in_list_p(pt_source, source_l)) {
99  if(points_to_cell_equal_p(pt_source, source)) {
100  /* We must generate a new source with the offset defined by sel,
101  and a new sink, with or without a an offset */
102  cell pt_sink = points_to_sink(pt);
103  cell n_source = cell_undefined;
104 
105  /* Update the source cell */
106  if(null_cell_p(pt_source)) {
107  pips_internal_error("NULL cannot be a source cell.\n");;
108  }
109  else if(anywhere_cell_p(pt_source)
110  || cell_typed_anywhere_locations_p(pt_source)) {
111  pips_internal_error("Not sure what should be done here!\n");
112  }
113  else {
114  n_source = copy_cell(pt_source);
115  reference n_source_r = cell_any_reference(n_source);
116  if(adapt_reference_to_type(n_source_r, at,
118  reference_indices(n_source_r) = gen_nconc(reference_indices(n_source_r),
119  gen_full_copy_list(sel));
121  }
122  else
123  pips_internal_error("No idea how to deal with this source cell.\n");
124  }
125 
126  /* Is the source cell already known in the points-to relation? */
127 
128  if(!cell_undefined_p(n_source) && !source_in_pt_map_p(n_source, in)) {
129  cell n_sink = copy_cell(pt_sink);
130 
131  /* Update the sink cell if necessary */
132  if(null_cell_p(pt_sink)) {
133  ;
134  }
135  else if(anywhere_cell_p(pt_sink)
136  || cell_typed_anywhere_locations_p(pt_sink)) {
137  ;
138  }
139  else {
140  reference n_sink_r = cell_any_reference(n_sink);
141  if(adapt_reference_to_type(n_sink_r, apt,
143  reference_indices(n_sink_r) = gen_nconc(reference_indices(n_sink_r),
144  gen_full_copy_list(sel));
146  }
147  else
148  pips_internal_error("No idea how to deal with this sink cell.\n");
149  }
150 
151  /* Build the new points-to arc */
153  points_to n_pt = make_points_to(n_source, n_sink, ap,
155  /* Do not update set "in" while you are enumerating its elements */
156  n_arc_l = CONS(POINTS_TO, n_pt, n_arc_l);
157  }
158  else
159  free_cell(n_source);
160  }
161  }
162  }
163  }
164 
165  /* Update sets "in" with the new arcs. The arc must pre-exist the
166  reference for the effects to be able to translate a non-constant
167  effect. Thus, it should pre-exist the call site. */
168  FOREACH(POINTS_TO, n_pt, n_arc_l) {
169  add_arc_to_pt_map(n_pt, in);
172  }
173  gen_free_list(n_arc_l);
174 
175  /* FI: I am not sure this is useful... */
176  in = expression_to_points_to(a, in, false); // side effects
177 
178  in = expressions_to_points_to(sel, in, false);
179 
180  free_type(at);
181  return in;
182 }
void free_cell(cell p)
Definition: effects.c:249
approximation copy_approximation(approximation p)
APPROXIMATION.
Definition: effects.c:132
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)
points_to copy_points_to(points_to p)
POINTS_TO.
void free_type(type p)
Definition: ri.c:2658
#define add_arc_to_pt_map(a, s)
#define source_in_pt_map_p(cell, set)
bool cell_typed_anywhere_locations_p(cell c)
test if a cell is the bottom of the lattice
pt_map dereferencing_to_points_to(expression p, pt_map in)
Make sure that expression p can be dereferenced in points-to graph "in".
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
bool points_to_cell_equal_p(cell, cell)
Definition: points_to.c:916
bool anywhere_cell_p(cell)
Is it an anywhere cell?
Definition: effects.c:367
bool adapt_reference_to_type(reference, type, int(*)(void))
FI: a really stupid function...
Definition: type.c:1327
void complete_points_to_reference_with_zero_subscripts(reference)
Definition: points_to.c:745
bool null_cell_p(cell)
Definition: effects.c:466
#define cell_undefined_p(x)
Definition: effects.h:431
#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
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#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
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
#define pips_internal_error
Definition: misc-local.h:149
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
void add_arc_to_points_to_context(points_to pt)
FI: it should rather work the other way round, with add_arc_to_statement_points_to_context() calling ...
Definition: passes.c:268
pt_map expressions_to_points_to(list el, pt_map pt_in, bool side_effect_p)
Compute the points-to information pt_out that results from the evaluation of a possibly empty list of...
Definition: expression.c:243
pt_map expression_to_points_to(expression e, pt_map pt_in, bool side_effect_p)
Update pt_in and pt_out according to expression e.
Definition: expression.c:115
void add_arc_to_statement_points_to_context(points_to)
Definition: statement.c:104
list expression_to_points_to_sources(expression, pt_map)
expression_to_points_to_sources() does not always work, especially with pointer arithmetic or subscri...
Definition: sinks.c:1805
int points_to_context_statement_line_number(void)
Definition: statement.c:120
#define points_to_approximation(x)
#define points_to_sink(x)
#define POINTS_TO(x)
POINTS_TO.
#define points_to_graph_set(x)
#define points_to_source(x)
bool array_type_p(type)
Definition: type.c:2942
type expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486
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 entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
#define reference_variable(x)
Definition: ri.h:2326
#define subscript_indices(x)
Definition: ri.h:2563
#define reference_indices(x)
Definition: ri.h:2328
#define subscript_array(x)
Definition: ri.h:2561
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References adapt_reference_to_type(), add_arc_to_points_to_context(), add_arc_to_pt_map, add_arc_to_statement_points_to_context(), anywhere_cell_p(), array_type_p(), CELL, cell_any_reference(), cell_typed_anywhere_locations_p(), cell_undefined, cell_undefined_p, complete_points_to_reference_with_zero_subscripts(), CONS, copy_approximation(), copy_cell(), copy_points_to(), dereferencing_to_points_to(), entity_basic_concrete_type(), expression_to_points_to(), expression_to_points_to_sources(), expression_to_type(), expressions_to_points_to(), FOREACH, free_cell(), free_type(), gen_free_list(), gen_full_copy_list(), gen_nconc(), make_descriptor_none(), make_points_to(), NIL, null_cell_p(), pips_internal_error, POINTS_TO, points_to_approximation, points_to_cell_equal_p(), points_to_context_statement_line_number(), points_to_graph_set, points_to_sink, points_to_source, reference_indices, reference_variable, SET_FOREACH, source_in_pt_map_p, subscript_array, subscript_indices, and type_to_pointed_type().

Referenced by dereferencing_to_points_to().

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

◆ dereferencing_to_points_to()

pt_map dereferencing_to_points_to ( expression  p,
pt_map  in 
)

Make sure that expression p can be dereferenced in points-to graph "in".

Handling of NULL pointers according to property.

Handling of undefined pointers according to property.

"in" is modified by side effects. Arcs certainly incompatible with a dereferencing are removed. If dereferencing of p is no longer possible, return an empty points-to "in" as the expression cannot be evaluated.

This is conditional to two properties.

ut =

You must take care of s.tab, which is encoded by a call

EffectsWithPointsTo/struct08.c: ae = (e.champ)[i], fe = p

For side effects on "in"

Parameters
inn

Definition at line 198 of file dereferencing.c.

199 {
200  //pt_map out = in;
201  bool null_dereferencing_p
202  = get_bool_property("POINTS_TO_NULL_POINTER_DEREFERENCING");
203  bool nowhere_dereferencing_p
204  = get_bool_property("POINTS_TO_UNINITIALIZED_POINTER_DEREFERENCING");
205  // FI: we cannot use expression_to_points_to_sources or sinks
206  // because side effects are taken into acount each time they are
207  // called.
208  if(!nowhere_dereferencing_p && !null_dereferencing_p) {
209  syntax s = expression_syntax(p);
210  tag t = syntax_tag(s);
211 
212  switch(t) {
213  case is_syntax_reference: {
215  /*out = */reference_dereferencing_to_points_to(r, in,
216  nowhere_dereferencing_p,
217  null_dereferencing_p);
218  break;
219  }
220  case is_syntax_range: {
221  //range r = syntax_range(s);
222  // out = range_to_points_to(r, in);
223  break;
224  }
225  case is_syntax_call: {
226  call c = syntax_call(s);
227  list al = call_arguments(c);
228 
229  // FI: you do not want to apply side-effects twice...
230  // But you then miss the detection of pointers that are not NULL
231  // because they are dereferenced and you miss the recursive descent
232  //in = expressions_to_points_to(al, in, false);
233  //in = call_to_points_to(c, in, el, false);
234 
235  /* You must take care of s.tab, which is encoded by a call */
236  entity f = call_function(c);
237  if(ENTITY_FIELD_P(f)) {
238  expression ae = EXPRESSION(CAR(al));
239  expression fe = EXPRESSION(CAR(CDR(al)));
240  /* EffectsWithPointsTo/struct08.c: ae = (e.champ)[i], fe = p*/
241  //pips_assert("ae and fe are references",
242  // expression_reference_p(ae) && expression_reference_p(fe));
243  pips_assert("fe is a reference", expression_reference_p(fe));
245  entity fv = reference_variable(fr);
247  if(pointer_type_p(ft) || struct_type_p(ft)
249  || array_of_struct_type_p(ft)) {
250  in = dereferencing_to_points_to(ae, in);
251  /* For side effects on "in" */
252  list sink_l = expression_to_points_to_sinks(p, in);
253  gen_free_list(sink_l);
254  }
255  }
256  else {
257  // Do not take side-effects into account or they will be applied twice
258  in = expressions_to_points_to(al, in, false);
259  in = call_to_points_to(c, in, NIL, false);
261  gen_free_list(sl);
262  }
263  break;
264  }
265  case is_syntax_cast: {
266  //cast c = syntax_cast(s);
267  //expression ce = cast_expression(c);
268  //out = expression_to_points_to(ce, in);
269  break;
270  }
272  //sizeofexpression soe = syntax_sizeofexpression(s);
273  //if(sizeofexpression_type_p(soe))
274  //; // in is not modified
275  //else {
276  // expression ne = sizeofexpression_expression(soe);
277  // FI: we have a problem because sizeof(*p) does not imply that
278  // *p is evaluated...
279  // out = expression_to_points_to(ne, in);
280  //;
281  //}
282  break;
283  }
284  case is_syntax_subscript: {
285  subscript sub = syntax_subscript(s);
287  break;
288  }
289  case is_syntax_application: {
290  // FI: we might have to go down here...
291  //application a = syntax_application(s);
292  //out = application_to_points_to(a, out);
293  break;
294  }
295  case is_syntax_va_arg: {
296  // The call to va_arg() does not create a points-to per se
297  //list soel = syntax_va_arg(s);
298  //sizeofexpression soe1 = SIZEOFEXPRESSION(CAR(soel));
299  //sizeofexpression soe2 = SIZEOFEXPRESSION(CAR(CDR(soel)));
300  //expression se = sizeofexpression_expression(soe1);
301  // type t = sizeofexpression_type(soe2);
302  //out = expression_to_points_to(se, out);
303  break;
304  }
305  default:
306  ;
307  }
308  }
309  return in;
310 }
pt_map reference_dereferencing_to_points_to(reference r, pt_map in, bool nowhere_dereferencing_p, bool null_dereferencing_p)
Can we execute the reference r in points-to context "in" without segfaulting?
pt_map dereferencing_subscript_to_points_to(subscript sub, pt_map in)
FI: As usual in dereferencing.c, it is not clear that this piece of code has not been implemented som...
Definition: dereferencing.c:71
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
int tag
TAG.
Definition: newgen_types.h:92
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
pt_map call_to_points_to(call c, pt_map pt_in, list el, bool side_effect_p)
Three different kinds of calls are distinguished:
Definition: expression.c:306
list expression_to_points_to_sinks(expression, pt_map)
The returned list contains cells used in "in".
Definition: sinks.c:1795
#define ENTITY_FIELD_P(e)
C data structure and pointer management.
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
bool array_of_pointers_type_p(type)
Definition: type.c:3025
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
bool struct_type_p(type)
Returns true if t is of type derived and if the derived type is a struct.
Definition: type.c:3121
bool array_of_struct_type_p(type)
Definition: type.c:3133
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define call_function(x)
Definition: ri.h:709
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_va_arg
Definition: ri.h:2698
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define syntax_call(x)
Definition: ri.h:2736
#define syntax_subscript(x)
Definition: ri.h:2745
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247

References array_of_pointers_type_p(), array_of_struct_type_p(), call_arguments, call_function, call_to_points_to(), CAR, CDR, dereferencing_subscript_to_points_to(), entity_basic_concrete_type(), ENTITY_FIELD_P, EXPRESSION, expression_reference(), expression_reference_p(), expression_syntax, expression_to_points_to_sinks(), expressions_to_points_to(), f(), gen_free_list(), get_bool_property(), is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, is_syntax_va_arg, NIL, pips_assert, pointer_type_p(), reference_dereferencing_to_points_to(), reference_variable, struct_type_p(), syntax_call, syntax_reference, syntax_subscript, and syntax_tag.

Referenced by dereferencing_subscript_to_points_to(), expression_to_points_to(), intrinsic_call_condition_to_points_to(), intrinsic_call_to_points_to(), and reference_to_points_to().

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

◆ dereferencing_to_sinks()

list dereferencing_to_sinks ( expression  a,
pt_map  in,
bool  eval_p 
)

Returns "sinks", the list of cells pointed to by expression "a" according to points-to graph "in".

If eval_p is true, perform a second dereferencing on the cells obtained with the first dereferencing.

Manage NULL and undefined (nowhere) cells.

Possibly update the points-to graph when some arcs are incompatible with the request, assuming the analyzed code is correct.

Locate the pointer, no dereferencing yet... unless no pointer can be found as in *(p+2) in which case an evaluation occurs/might occur/used to occur in expression_to_points_to_sources().

lse

Finds what it is pointing to, memory(p)

Do we want to dereference c?

Do not create sharing between elements of "in" and elements of "sinks".

The sinks list is empty, whether eval_p is true or not...

FI: New cells have been allocated by source_to_sinks(): side-effects are OK. In theory... The source code of source_to_sinks() seems to show that fresh_p is not exploited in all situations.

Parameters
inn
eval_pval_p

Definition at line 432 of file dereferencing.c.

433 {
434  list sinks = NIL;
435  /* Locate the pointer, no dereferencing yet... unless no pointer can
436  be found as in *(p+2) in which case an evaluation occurs/might
437  occur/used to occur in expression_to_points_to_sources(). */
439  if(ENDP(cl)) {
440  // The source may not be found, e.g. *(p+i)
441  //sinks = expression_to_points_to_sinks(a, in);
442  cl = expression_to_points_to_sinks(a, in);
443  }
444  /*else*/ { // Some sources have been found
446  bool evaluated_p = !expression_to_points_to_cell_p(a);
447  // evaluated_p = false;
448  if(!evaluated_p || eval_p) {
449  bool null_dereferencing_p
450  = get_bool_property("POINTS_TO_NULL_POINTER_DEREFERENCING");
451  bool nowhere_dereferencing_p
452  = get_bool_property("POINTS_TO_UNINITIALIZED_POINTER_DEREFERENCING");
453 
454  /* Finds what it is pointing to, memory(p) */
455  FOREACH(CELL, c, cl) {
456  /* Do we want to dereference c? */
457  if( (null_dereferencing_p || !null_cell_p(c))
458  && (nowhere_dereferencing_p || !nowhere_cell_p(c))) {
459  list o_pointed = source_to_sinks(c, in, true);
460  remove_impossible_arcs_to_null(&o_pointed, in);
461  /* Do not create sharing between elements of "in" and elements of
462  "sinks". */
463  // list pointed = source_to_sinks(c, in, true);
464  list pointed = gen_full_copy_list(o_pointed);
465  gen_free_list(o_pointed);
466  if(ENDP(pointed)) {
468  entity v = reference_variable(r);
469  string words_to_string(list);
470  pips_user_warning("No pointed location for variable \"%s\" and reference \"%s\"\n",
471  entity_user_name(v),
473  /* The sinks list is empty, whether eval_p is true or not... */
474  }
475  else {
476  if(!evaluated_p && eval_p) {
477  FOREACH(CELL, sc, pointed) {
478  bool to_be_freed;
479  type t = points_to_cell_to_type(sc, &to_be_freed);
480  if(!pointer_type_p(t)) {
481  // FI: it might be necessary to allocate a new copy of sc
482  sinks = gen_nconc(sinks, CONS(CELL, sc, NIL));
483  }
484  else if(array_type_p(t) || struct_type_p(t)) {
485  /* FI: New cells have been allocated by
486  source_to_sinks(): side-effects are OK. In
487  theory... The source code of source_to_sinks() seems
488  to show that fresh_p is not exploited in all
489  situations. */
490  //cell nsc = copy_cell(sc);
491  //points_to_cell_add_zero_subscripts(nsc);
492  //sinks = gen_nconc(sinks, CONS(CELL, nsc, NIL));
493  pips_internal_error("sc assume saturated with 0 subscripts and/or field susbscripts.\n");
494  }
495  else {
496  list starpointed = pointer_source_to_sinks(sc, in);
497  // sinks = gen_nconc(sinks, starpointed);
498  sinks = merge_points_to_cell_lists(sinks, starpointed);
499  }
500  if(to_be_freed) free_type(t);
501  }
502  }
503  else
504  sinks = gen_nconc(sinks, pointed);
505  }
506  }
507  }
508  }
509  else
510  sinks = cl;
511  }
512 
513  return sinks;
514 }
bool expression_to_points_to_cell_p(expression e)
Can expression e be reduced to a reference, without requiring an evaluation?
type points_to_cell_to_type(cell, bool *)
FI: I need more generality than is offered by cell_to_type()
Definition: type.c:665
bool nowhere_cell_p(cell)
Target of an undefined pointer.
Definition: effects.c:455
list merge_points_to_cell_lists(list, list)
Add in "l1" elements of "l2" that are not yet in "l1".
Definition: points_to.c:134
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define pips_user_warning
Definition: misc-local.h:146
list pointer_source_to_sinks(cell, pt_map)
Returns the sinks for a source cell "sc" of type pointer according to the points-to relation "in".
void remove_impossible_arcs_to_null(list *, pt_map)
You know that null and undefined cells in "*pL" are impossible because of the operation that is going...
list source_to_sinks(cell, pt_map, bool)
Return a list of cells, "sinks", that are sink for some arc whose source is "source" or related to "s...
string reference_to_string(reference r)
Definition: expression.c:87
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
string words_to_string(cons *lw)
Definition: print.c:211

References array_type_p(), CELL, cell_any_reference(), CONS, ENDP, entity_user_name(), expression_to_points_to_cell_p(), expression_to_points_to_sinks(), expression_to_points_to_sources(), FOREACH, free_type(), gen_free_list(), gen_full_copy_list(), gen_nconc(), get_bool_property(), merge_points_to_cell_lists(), NIL, nowhere_cell_p(), null_cell_p(), pips_internal_error, pips_user_warning, pointer_source_to_sinks(), pointer_type_p(), points_to_cell_to_type(), reference_to_string(), reference_variable, remove_impossible_arcs_to_null(), source_to_sinks(), struct_type_p(), and words_to_string().

Referenced by unary_intrinsic_call_to_points_to_sinks().

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

◆ expression_to_points_to_cell_p()

bool expression_to_points_to_cell_p ( expression  e)

Can expression e be reduced to a reference, without requiring an evaluation?

For instance expression "p" can be reduced to reference "p".

Expression "p+i" cannot be reduced to a source reference, unless i==0.

Ad'hoc development for dereferencing_to_sinks.

Definition at line 406 of file dereferencing.c.

407 {
408  bool source_p = true;
409  syntax s = expression_syntax(e);
410  if(syntax_reference_p(s))
411  source_p = true;
412  else if(syntax_call_p(s)) {
413  call c = syntax_call(s);
414  entity f = call_function(c);
415  if(ENTITY_PLUS_C_P(f))
416  source_p = false;
417  }
418  return source_p;
419 }
#define ENTITY_PLUS_C_P(e)
#define syntax_reference_p(x)
Definition: ri.h:2728
#define syntax_call_p(x)
Definition: ri.h:2734

References call_function, ENTITY_PLUS_C_P, expression_syntax, f(), syntax_call, syntax_call_p, and syntax_reference_p.

Referenced by dereferencing_to_sinks(), and expression_to_points_to_sources().

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

◆ pointer_points_to_reference_p()

bool pointer_points_to_reference_p ( reference r   __attribute__(unused))

see if a points_to_reference includes a pointer dereferencing: this is impossible if the points-to reference is consistent.

It must be a constant path.

Definition at line 313 of file dereferencing.c.

314 {
315  return false;
316 }

Referenced by reference_dereferencing_to_points_to().

+ Here is the caller graph for this function:

◆ pointer_reference_dereferencing_to_points_to()

void pointer_reference_dereferencing_to_points_to ( reference  r,
pt_map  in 
)
Parameters
inn

Definition at line 318 of file dereferencing.c.

319 {
321  // FI: assume side effects are OK...
322  (void) expression_to_points_to(pae, in, true);
323  free_expression(pae);
324 }
void free_expression(expression p)
Definition: ri.c:853
expression pointer_reference_to_expression(reference r)
Assume p is a pointer.
Definition: expression.c:4004

References expression_to_points_to(), free_expression(), and pointer_reference_to_expression().

Referenced by reference_dereferencing_to_points_to().

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

◆ reference_dereferencing_to_points_to()

pt_map reference_dereferencing_to_points_to ( reference  r,
pt_map  in,
bool  nowhere_dereferencing_p,
bool  null_dereferencing_p 
)

Can we execute the reference r in points-to context "in" without segfaulting?

Do not go down in subscript expressions.

See also reference_to_points_to_sinks(). Unfortunate cut-and-paste.

Does the reference implies some dereferencing itself?

C syntactic sugar: *a is equivalent to a[0] when a is an array. No real dereferencing needed.

Remove store-dependent indices

Parameters
inn
nowhere_dereferencing_powhere_dereferencing_p
null_dereferencing_pull_dereferencing_p

Definition at line 333 of file dereferencing.c.

337 {
338  entity e = reference_variable(r);
340  list sl = reference_indices(r);
341 
342  /* Does the reference implies some dereferencing itself? */
343  // FI: I do not remember what this means; examples are nice
346  }
347  else if(pointer_type_p(t) && !ENDP(sl)) {
349  }
350  else if(array_of_pointers_type_p(t)
353  }
354  else if(array_type_p(t) && !array_of_pointers_type_p(t)) {
355  /* C syntactic sugar: *a is equivalent to a[0] when a is an
356  array. No real dereferencing needed. */
357  ;
358  }
359  else {
360  // FI: I am confused here
361  // FI: we might have to do more when a struct or an array is referenced
362  if(pointer_type_p(t) || array_of_pointers_type_p(t)) { // FI: implies ENDP(sl)
363  reference nr = copy_reference(r);
364  cell source = make_cell_reference(nr);
365  /* Remove store-dependent indices */
366  reference_indices(nr) =
368  list sinks = source_to_sinks(source, in, false);
369  int n = (int) gen_length(sinks);
370  FOREACH(CELL, sink, sinks) {
371  if(!nowhere_dereferencing_p && nowhere_cell_p(sink)) {
372  remove_points_to_arcs(source, sink, in);
373  n--;
374  }
375  if(!null_dereferencing_p && null_cell_p(sink)) {
376  remove_points_to_arcs(source, sink, in);
377  n--;
378  }
379  }
380  if(n==0) {
381  clear_pt_map(in);
382  points_to_graph_bottom(in) = true;
384  semantics_user_warning("Null or undefined pointer may be dereferenced because of \"%s\" at line %d.\n",
387  else
388  semantics_user_warning("Null or undefined pointer may be dereferenced because of \"%s\".\n",
390  }
391 
392  gen_free_list(sinks);
393  }
394  }
395  return in;
396 }
cell make_cell_reference(reference _field_)
Definition: effects.c:293
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
#define clear_pt_map(pt)
void const char const char const int
bool pointer_points_to_reference_p(reference r __attribute__((unused)))
see if a points_to_reference includes a pointer dereferencing: this is impossible if the points-to re...
void pointer_reference_dereferencing_to_points_to(reference r, pt_map in)
string effect_reference_to_string(reference)
Definition: prettyprint.c:155
size_t gen_length(const list l)
Definition: list.c:150
bool statement_points_to_context_defined_p(void)
Definition: statement.c:145
void remove_points_to_arcs(cell, cell, pt_map)
#define points_to_graph_bottom(x)
list subscript_expressions_to_constant_subscript_expressions(list sl)
make a full copy of the subscript expression list, preserve constant subscripts, replace non-constant...
Definition: expression.c:3981
int variable_dimension_number(variable)
Definition: type.c:5632
#define type_variable(x)
Definition: ri.h:2949
#define semantics_user_warning

References array_of_pointers_type_p(), array_type_p(), CELL, clear_pt_map, copy_reference(), effect_reference_to_string(), ENDP, entity_basic_concrete_type(), FOREACH, gen_free_list(), gen_length(), int, make_cell_reference(), nowhere_cell_p(), null_cell_p(), pointer_points_to_reference_p(), pointer_reference_dereferencing_to_points_to(), pointer_type_p(), points_to_context_statement_line_number(), points_to_graph_bottom, reference_indices, reference_variable, remove_points_to_arcs(), semantics_user_warning, source_to_sinks(), statement_points_to_context_defined_p(), subscript_expressions_to_constant_subscript_expressions(), type_variable, and variable_dimension_number().

Referenced by dereferencing_to_points_to().

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