PIPS
points_to_init_analysis.c
Go to the documentation of this file.
1 /*
2 
3  $Id: points_to_init_analysis.c 23645 2021-03-10 09:47:38Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 /* For strdup and asprintf: */
26 // Already defined elsewhere
27 #ifndef _GNU_SOURCE
28 #define _GNU_SOURCE
29 #endif
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include "genC.h"
36 #include "linear.h"
37 
38 #include "ri.h"
39 #include "effects.h"
40 
41 #include "bootstrap.h" // ???MakeIOFileArray
42 
43 #include "ri-util.h"
44 #include "effects-util.h"
45 
46 #include "misc.h"
47 
48 #include "text-util.h" // int2a
49 
50 #include "properties.h"
51 
52 #include "effects-generic.h"
53 #include "effects-simple.h"
54 
55 #include "points_to_private.h"
56 #include "points-to.h"
57 
58 static int pointer_index = 1;
59 
60 /* --------------------------------Interprocedural Points-to Analysis-----------------------*/
61 /* This package computes the points-to interprocedurally.
62  *
63  * See Chapter ? in Amira Mensi's PhD dissertation.
64  */
65 
67 {
68 
69 }
70 
72 {
73 }
74 /* We want a recursive descent on the type of the formal parameter,
75  * once we found a pointer type we beguin a recursive descent until
76  * founding a basic case. Then we beguin the ascent and the creation
77  * gradually of the points_to_stub by calling
78  * pointer_formal_parameter_to_stub_points_to().
79  *
80  * FI->AM: as I would rather work on-demand, this function should be
81  * useless. I fixed it nevertheless because it seems better for
82  * EffectsWithPointsTo, which does not seem to allocate the new
83  * points-to stubs it needs.
84  */
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 }
141 ␌
142 /* Allocate a stub entity "stub" for entity "e" and with type
143  * "t". Abort if "stub" already exists.
144  *
145  * It seems that type "t" could be derived from "e" since it should be
146  * the pointed type of "e"'s type, but it is not at all the case in
147  * general. Variable e is used to build a reference and the type
148  * pointed by the reference may be different when arrays of structs of
149  * arrays of structs are involved.
150  */
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 }
245 ␌
246 /* Create a stub entity "se" for entity "v" with type "t" and return a
247  * cell based on a reference to the stub entity "se" with "d"
248  * unbounded subscripts to account for the dimension of the source and
249  * a zero subscript for implicit array.
250  *
251  * Type "pt" is the theoretically expected type for the reference
252  * "sink_ref" within the returned cell, "sink_cell". We assert
253  * "pt==points_to_cell_to_type(sink_cell)".
254  *
255  * Type "t" must account for the extra "d" dimensions.
256  *
257  * The type strictness is handled by the caller.
258  *
259  * The name of the function is misleading. It should be
260  * "create_stub_sink_cell"... but in fact is does not handle the
261  * struct case because struct can contain may different pointers,
262  * directly or indirectly, depending on fields. This function is ok if
263  * v a pointer or an array of pointers, but not if v is a struct.
264  *
265  * The function is called four times from create_stub_points_to().
266  */
268  type st, // stub type
269  type pt, // sink cell type, pointed type
270  int d, // number of preexisting subscripts
271  list sl, // pre-existing subscripts
272  string fs) // disambiguator for fields
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 }
380 ␌
381 /* Count the number of array indices and ignore the field
382  * subscripts.
383  */
385 {
386  int c = 0;
387  FOREACH(EXPRESSION, s, sl) {
388  if(!expression_reference_p(s))
389  c++;
390  }
391  return c;
392 }
393 
394 /* FI: probably a duplicate... */
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 }
420 
421 /* Generate a new subscript list. References to fields are ignored,
422  * constant and unbounded expressions are preserved, non-constant
423  * expressions are replaced by unbounded expressions.
424  */
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 }
458 
459 /* Build an ASCII string to disambiguate the different field paths
460  * that may exist in similar references.
461  *
462  * If the variable referenced by "r" is not a struct, returns the
463  * empty string.
464  *
465  * If it is a struct, derive a string that is unique to a particular
466  * combination of fields and subfields.
467  */
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 }
492 
493 ␌
494 /* points_to create_stub_points_to(cell c, bool exact_p)
495  *
496  * To create the points-to arc "pt_to" between a cell "c" containing a
497  * constant path reference based on a formal parameter or a global
498  * variable or another stub on one hand, and another new points-to
499  * stub reference on the other.
500  *
501  * Argument "exact_p" specifies the approximation of the generated
502  * points-to arc. It is overriden when NULL pointers are distinguished
503  * according to property POINTS_TO_NULL_POINTER_INITIALIZATION. This
504  * simplifies the semantics of the stub entities: they cannot
505  * represent/hide the NULL abstract cell.
506  *
507  * The arc approximation itself is another issue as pointed out
508  * by Beatrice Creusillet because we may have an approximation on the
509  * source node, on the sink node or on the arc. Currently, an exact
510  * approximation seems to indicate that no approximation at all is
511  * made. This is issue is not currently solved (13 August 2012).
512  *
513  * Assumption: the reference in source cell "c" is a constant memory
514  * path. So is the new reference hidden in the sink cell.
515  *
516  * This function must be consistent with type compatibility checks
517  * used in points-to analysis, points_to_cell_types_compatibility(l, r).
518  *
519  * The global sink name of the generated stub is a concatenation of
520  * the formal parameter, underscore, some number, and
521  * POINTS_TO_MODULE_NAME as module name.
522  *
523  * The type of cell "c" and the type of the sink cell that is
524  * generated must fit in some complicated way:
525  *
526  * 1. Do we consider types to be strict or do we allow pointer
527  * arithmetic, which implies that pointers to scalars or anything else
528  * in fact points to arrays? This is controlled by property
529  * POINTS_TO_STRICT_POINTER_TYPES.
530  *
531  * 2. When the source is an array of pointers, do we add its
532  * dimensions to the type of the sink? Yes, to preserve the
533  * independence of independent cells (i.e. to be ready for a future
534  * version with descriptors, compatible with dependence testing).
535  *
536  * 3. When the source is a really subscripted reference to an array of
537  * pointers, how do we generate the subscripts of the sink? Especially
538  * if the source is partially subscripted? We try to copy the
539  * subscript to preserve as much information as possible.
540  *
541  * 4. Also, we have a choice: either point toward the first element of
542  * an implicit array or point towards the array itself. To be
543  * consistent with the interpretation of "p=a;" and "p=&a[0]", we
544  * chose to points towards the object itself. But Pass
545  * effects_with_points_to seems to expect pointers to the first array
546  * element. A normalization function could be used to switch from one
547  * convention to the other. The current idea is that, as much as
548  * possible, points-to "c1->c2" implies that "c1==&c2;" holds. So 0
549  * subscript are added to fill the last dimensions of the sink
550  * reference.
551  *
552  * Here, we needs lots of examples with constant memory path
553  * references to prepare a precise specification of the desired
554  * function. Let c stands for the reference hidden in cell "c":
555  *
556  * * assignment13.c: "c=_t2_2_2[0][ip2];": here we have an array of
557  * structs containing a pointer field. Beatrice would like us to infer
558  * _t2_2_2[*][ip2] -> _t2_2_2_2[*]... Imagine the general case with
559  * structs with arrays of structs with... We may also want an arc
560  * _t2_2_2[*][ip2] -> NULL (see property
561  * POINTS_TO_NULL_POINTER_INITIALIZATION), or even an arc
562  * _t2_2_2[*][ip2] -> UNDEFINED (not implemented because about useless
563  * since parameters are passed by value). We may also want:
564  * _t2_2_2[*][ip2] -> _t2_2_2_2[*][0]
565  *
566  * * "void foo(int *p) c=p;": depending on property on strict typing,
567  * POINTS_TO_STRICT_POINTER_TYPES, we want either p -> _p_1
568  * or p -> _p_1[0]
569  *
570  * * "void foo(int * pa[10]) {int * c=pa[0];}": pa[*] -> NULL, pa[*]
571  * -> _pa_1[*] but c->_pa_1[0]
572  *
573  * * ptr_to_array01.c: "int ptr_to_array01(int * (*p)[10]) {int a; (*p)[3] = &a;}"
574  * p->_p_1, p_1[3] -> a
575  *
576  * The cell "c" is not embedded in the generated points-to "pt_to". A
577  * copy is allocated. The output has no sharing with the input
578  * parameters.
579  */
580 points_to create_stub_points_to(cell c, // source of the points-to
581  type unused_st __attribute__ ((__unused__)), // expected type for the sink cell
582  // or the sink cell reference...
583  bool exact_p)
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 }
683 
684 /* Take into account the POINTS_TO_STRICT_POINTER_TYPE to allocate a
685  * sink cell of type "t" if the strictness is requested and of type
686  * "array of t" if not.
687  */
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 }
704 
705 /* To create the points-to stub associated to the formal parameter,
706  * the sink name is a concatenation of the formal parmater and the
707  * POINTS_TO_MODULE_NAME.
708  */
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 }
796 
797 
798 /* Input : a formal parameter which is a pointer and its type.
799  *
800  * Output : a set of points-to where sinks are stub points-to.
801  * we descent recursively until reaching a basic type, then we call
802  * create_stub_points_to()to generate the adequate points-to.
803  *
804  * FI: I do not know if I want to keep using this function because
805  * stubs are not created on demand and because some are certainly not
806  * useful for the points-to analysis. But they may be useful for
807  * client analysis... However, client analyses will have to create
808  * more such stubs...
809  */
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 }
943 
944 
945 
946 /* Input : a formal parameter which has a derived type (FI, I guess).
947  * output : a set of points-to where sinks are stub points-to.
948  *
949  * FI: a lot of rewrite needed to simplify. Also, do not forget that
950  * NULL maybe the received value.
951  */
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 }
1027 
1028 /* Input : a formal parameter which is a typedef.
1029  *
1030  * FI: a formal parameter cannot be a typedef, but it can be typed
1031  * with a typedefined type.
1032  */
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 }
1105 
1106 
1107 /* Type "t" is supposed to be a concrete type.
1108  *
1109  * Type "t" may be modified: no.
1110  *
1111  * Cell "c" is copied.
1112  *
1113  * The dimensions of type "t" are forgotten. They are retrieved later
1114  * from the type of the entity references in cell "c".
1115  */
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 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
cell make_cell_reference(reference _field_)
Definition: effects.c:293
approximation make_approximation_exact(void)
Definition: effects.c:185
approximation make_approximation_may(void)
Definition: effects.c:179
bool cell_consistent_p(cell p)
Definition: effects.c:255
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)
bool reference_consistent_p(reference p)
Definition: ri.c:2056
value make_value_unknown(void)
Definition: ri.c:2847
type make_type_variable(variable _field_)
Definition: ri.c:2715
storage make_storage_rom(void)
Definition: ri.c:2285
entity gen_find_entity(char *s)
Definition: ri.c:2551
type copy_type(type p)
TYPE.
Definition: ri.c:2655
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
basic make_basic_overloaded(void)
Definition: ri.c:167
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
area make_area(intptr_t a1, list a2)
Definition: ri.c:98
void free_expression(expression p)
Definition: ri.c:853
void free_type(type p)
Definition: ri.c:2658
storage make_storage_ram(ram _field_)
Definition: ri.c:2279
type make_type(enum type_utype tag, void *val)
Definition: ri.c:2706
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
#define add_arc_to_simple_pt_map(a, s)
bool entity_stub_sink_p(entity e)
test if an entity is a stub sink for a formal parameter e.g.
bdt base
Current expression.
Definition: bdt_read_paf.c:100
entity MakeIoFileArray(entity f)
This array is pointed by FILE * pointers returned or used by fopen, fclose,...
Definition: bootstrap.c:5705
bool expression_is_constant_p(expression e)
BEGIN_EOLE.
Definition: constant.c:666
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.
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
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
cell make_null_pointer_value_cell(void)
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
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 effect_undefined
Definition: effects.h:614
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void free(void *)
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
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
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
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#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
#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 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 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 pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define asprintf
Definition: misc-local.h:225
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define FORMAL_AREA_LOCAL_NAME
Definition: naming-local.h:76
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#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
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
void set_free(set)
Definition: set.c:332
set set_union(set, const set, const set)
Definition: set.c:211
@ set_private
Definition: newgen_set.h:45
set set_add_element(set, const set, const void *)
Definition: set.c:152
#define string_undefined
Definition: newgen_types.h:40
char * string
STRING.
Definition: newgen_types.h:39
#define string_undefined_p(s)
Definition: newgen_types.h:41
#define UU
Definition: newgen_types.h:98
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
_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
set array_formal_parameter_to_stub_points_to(type t, cell c)
Type "t" is supposed to be a concrete type.
static int pointer_index
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 ...
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 strict...
set pointer_formal_parameter_to_stub_points_to(type pt, cell c)
Input : a formal parameter which is a pointer and its type.
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.
void points_to_backward_translation()
set derived_formal_parameter_to_stub_points_to(type pt, cell c)
Input : a formal parameter which has a derived type (FI, I guess).
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 ...
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 begu...
void points_to_indices_to_unbounded_indices(list sl)
FI: probably a duplicate...
void points_to_forward_translation()
-----------------------------—Interprocedural Points-to Analysis--------------------—
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)
entity create_stub_entity(entity e, string fs, type t)
Allocate a stub entity "stub" for entity "e" and with type "t".
set typedef_formal_parameter_to_stub_points_to(type pt, cell c)
Input : a formal parameter which is a typedef.
#define points_to_undefined
#define points_to_sink(x)
#define print_points_to_cell(x)
Definition: print.c:377
void print_type(type)
For debugging.
Definition: type.c:111
#define make_entity(n, t, s, i)
#define FOPEN_FUNCTION_NAME
#define ENTITY_STDIN_P(e)
#define FIELD_OPERATOR_NAME
Definition: ri-util-local.h:91
#define DYNAMIC_RAM_OFFSET
FI: I would have assumed that it is used for the stack area, but I must be wrong.....
#define UNKNOWN_RAM_OFFSET
#define DEFAULT_CHARACTER_TYPE_SIZE
Default type sizes.
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
#define ENTITY_STDERR_P(e)
#define ENTITY_STDOUT_P(e)
@ ENTITY_POINTER_DUMMY_TARGETS_AREA
@ ENTITY_FORMAL_AREA
@ ABSTRACT_LOCATION
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
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
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
bool array_entity_p(entity e)
Definition: entity.c:793
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
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
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
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
bool extended_integer_constant_expression_p(expression e)
More extensive than next function.
Definition: expression.c:858
expression make_unbounded_expression()
Definition: expression.c:4339
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
expression make_zero_expression(void)
Make a zero expression.
Definition: expression.c:1212
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 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
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
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
type ultimate_type(type)
Definition: type.c:3466
bool array_type_p(type)
Definition: type.c:2942
list make_unbounded_dimensions(int)
Minimal information to build a d-dimensional array type.
Definition: type.c:5752
bool scalar_type_p(type)
Definition: type.c:2955
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
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
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
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 variable_dimension_number(variable)
Definition: type.c:5632
int add_C_variable_to_area(entity, entity)
Definition: variable.c:1381
bool basic_equal_p(basic, basic)
Definition: type.c:927
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
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 make_scalar_integer_type(_int)
Definition: type.c:712
bool formal_parameter_p(entity)
Definition: variable.c:1489
type MakeTypeOverloaded(void)
Definition: type.c:107
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
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 formal_offset(x)
Definition: ri.h:1408
@ 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 type_struct(x)
Definition: ri.h:2964
#define basic_pointer(x)
Definition: ri.h:637
#define type_struct_p(x)
Definition: ri.h:2962
#define reference_undefined
Definition: ri.h:2302
#define EXPRESSION_(x)
Definition: ri.h:1220
#define reference_variable(x)
Definition: ri.h:2326
#define basic_derived(x)
Definition: ri.h:640
#define basic_typedef_p(x)
Definition: ri.h:641
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define dimension_lower(x)
Definition: ri.h:980
#define basic_tag(x)
Definition: ri.h:613
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#define basic_derived_p(x)
Definition: ri.h:638
#define entity_storage(x)
Definition: ri.h:2794
@ is_value_unknown
Definition: ri.h:3035
#define storage_formal(x)
Definition: ri.h:2524
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define basic_typedef(x)
Definition: ri.h:643
#define type_undefined_p(x)
Definition: ri.h:2884
#define basic_undefined
Definition: ri.h:556
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
#define type_void_p(x)
Definition: ri.h:2959
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define variable_dimensions(x)
Definition: ri.h:3122
#define storage_ram(x)
Definition: ri.h:2521
#define type_undefined
Definition: ri.h:2883
#define entity_kind(x)
Definition: ri.h:2798
@ is_type_area
Definition: ri.h:2899
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120
#define ram_offset(x)
Definition: ri.h:2251
#define entity_initial(x)
Definition: ri.h:2796
Value b2
Definition: sc_gram.c:105
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
char * int2a(int)
util.c
Definition: util.c:42