PIPS
effects-util.h File Reference
#include "linear.h"
#include "newgen.h"
#include "ri.h"
#include "effects.h"
#include "points_to_private.h"
+ Include dependency graph for effects-util.h:

Go to the source code of this file.

Data Structures

struct  sensitivity_information
 

Macros

#define ANY_MODULE_NAME   "*ANY_MODULE*"
 Warning! Do not modify this file that is automatically generated! More...
 
#define ANYWHERE_LOCATION   "*ANYWHERE*"
 
#define NOWHERE_LOCATION   "*NOWHERE*"
 
#define NULL_POINTER_NAME   "*NULL*"
 
#define UNDEFINED_LOCATION   "*UNDEFINED*"
 
#define UNDEFINED_POINTER_VALUE_NAME   "*UNDEFINED*"
 
#define NULL_POINTER_VALUE_NAME   "*NULL*"
 
#define PHI_PREFIX   "PHI"
 
#define PSI_PREFIX   "PSI"
 
#define RHO_PREFIX   "RHO"
 
#define BETA_PREFIX   "BETA"
 
#define PROPER   true
 
#define SUMMARY   false
 
#define effect_any_entity(e)   effect_to_entity(e)
 some useful SHORTHANDS for EFFECT: More...
 
#define effect_action_tag(eff)   action_tag(effect_action(eff))
 
#define effect_approximation_tag(eff)    approximation_tag(effect_approximation(eff))
 
#define effect_read_p(eff)   (action_tag(effect_action(eff))==is_action_read)
 #define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff)) More...
 
#define effect_write_p(eff)   (action_tag(effect_action(eff))==is_action_write)
 
#define effect_may_p(eff)    (approximation_tag(effect_approximation(eff)) == is_approximation_may)
 
#define effect_must_p(eff)    (approximation_tag(effect_approximation(eff)) == is_approximation_must)
 
#define effect_exact_p(eff)    (approximation_tag(effect_approximation(eff)) ==is_approximation_exact)
 
#define effect_variable(e)   reference_variable(effect_any_reference(e))
 For COMPATIBILITY purpose only - DO NOT USE anymore. More...
 
#define variable_phi_p(e)
 true if e is a phi variable PHI entities have a name like: REGIONS:PHI#, where # is a number. More...
 
#define variable_psi_p(e)
 
#define variable_rho_p(e)
 
#define variable_beta_p(e)
 
#define effect_system(e)
 
#define effect_reference(e)
 FI: it would be useful to assert cell_preference_p(effect_cell(e)), but I do not know how to do it in such a way that it works both for left hand sides and right hand sides using commas. More...
 
#define effect_any_reference(e)    (cell_preference_p(effect_cell(e))? preference_reference(cell_preference(effect_cell(e))) : cell_reference(effect_cell(e)))
 FI: cannot be used as a left hand side. More...
 
#define make_preference_simple_effect(reference, action, approximation)
 
#define make_reference_simple_effect(reference, action, approximation)
 
#define make_simple_effect(reference, action, approximation)
 
#define make_convex_effect(reference, action, approximation, system)
 
#define cell_relation_first_cell(cr)    interpreted_cell_cell(cell_relation_first(cr))
 
#define cell_relation_first_interpretation_tag(cr)    cell_interpretation_tag(interpreted_cell_cell_interpretation(cell_relation_first(cr)))
 
#define cell_relation_first_value_of_p(cr)    cell_interpretation_value_of_p(interpreted_cell_cell_interpretation(cell_relation_first(cr)))
 
#define cell_relation_first_address_of_p(cr)    cell_interpretation_address_of_p(interpreted_cell_cell_interpretation(cell_relation_first(cr)))
 
#define cell_relation_second_cell(cr)    interpreted_cell_cell(cell_relation_second(cr))
 
#define cell_relation_second_interpretation_tag(cr)    cell_interpretation_tag(interpreted_cell_cell_interpretation(cell_relation_second(cr)))
 
#define cell_relation_second_value_of_p(cr)    cell_interpretation_value_of_p(interpreted_cell_cell_interpretation(cell_relation_second(cr)))
 
#define cell_relation_second_address_of_p(cr)    cell_interpretation_address_of_p(interpreted_cell_cell_interpretation(cell_relation_second(cr)))
 
#define cell_relation_approximation_tag(cr)    approximation_tag(cell_relation_approximation(cr))
 
#define cell_relation_may_p(cr)    approximation_tag(cell_relation_approximation(cr))==is_approximation_may
 
#define cell_relation_exact_p(cr)    approximation_tag(cell_relation_approximation(cr))==is_approximation_exact
 
#define pips_debug_pv(level, message, pv)
 
#define pips_debug_pvs(level, message, l_pv)
 

Functions

entity effect_entity (effect)
 cproto-generated files More...
 
entity cell_entity (cell)
 
list cell_indices (cell)
 
reference cell_any_reference (cell)
 API for reference. More...
 
bool memory_dereferencing_p (reference)
 Does the set of locations referenced by r depend on a pointer dereferencing? More...
 
effects list_to_effects (list)
 Future API for GAP, Generic Access Path. More...
 
list effects_to_list (effects)
 
statement_mapping listmap_to_effectsmap (statement_mapping)
 
statement_mapping effectsmap_to_listmap (statement_mapping)
 
bool statement_has_a_module_formal_argument_write_effect_p (statement, entity, statement_mapping)
 Return true if the statement has a write effect on at least one of the argument (formal parameter) of the module. More...
 
bool cell_abstract_location_p (cell)
 
bool effect_abstract_location_p (effect)
 
bool effects_abstract_location_p (list)
 Returns true if at least one effect of effect list el is related to an abstract location. More...
 
effect anywhere_effect (action)
 Anywhere effect: an effect which can be related to any location of any areas. More...
 
bool anywhere_effect_p (effect)
 Is it an anywhere effect? ANYMMODULE:ANYWHERE More...
 
bool typed_anywhere_effect_p (effect)
 Is it a typed anywhere effect? ANYMMODULE:ANYWHERE_b0, 1, 2. More...
 
bool any_anywhere_effect_p (effect)
 Is it a typed or untyped anywhere effect? More...
 
bool anywhere_cell_p (cell)
 Is it an anywhere cell? More...
 
bool anywhere_reference_p (reference)
 
effect heap_effect (entity, action)
 
bool heap_effect_p (effect)
 
bool heap_cell_p (cell)
 Any heap cell, more or less abstract or typed. More...
 
bool all_heap_locations_cell_p (cell)
 
bool nowhere_cell_p (cell)
 Target of an undefined pointer. More...
 
bool null_cell_p (cell)
 
bool malloc_effect_p (effect)
 
bool malloc_cell_p (cell)
 
bool malloc_reference_p (reference)
 
bool io_effect_entity_p (entity)
 
bool io_effect_p (effect)
 
bool io_cell_p (cell)
 
bool io_effects_p (list effects)
 
bool std_file_effect_p (effect)
 
bool std_file_cell_p (cell)
 
bool std_file_effects_p (list effects)
 
bool FILE_star_effect_reference_p (reference)
 
bool effect_scalar_p (effect)
 
bool effect_comparable_p (effect, effect)
 Can we merge these two effects because they are equal or because they only differ by their approximations and their descriptors? More...
 
bool store_independent_effect_p (effect)
 Does this effect define the same set of memory locations regardless of the current (environment and) memory state? More...
 
bool effect_on_non_local_variable_p (effect)
 Test if an effect has a non local effect. More...
 
bool effects_on_non_local_variable_p (list effects)
 Test if a list of effects concerns non local variables. More...
 
bool effects_interfere_p (effect, effect)
 Two effects interfere if one of them modify the set of locations defined by the other one. More...
 
effect effect_to_store_independent (effect)
 
effect effect_to_pointer_store_independent_effect (effect, entity)
 Modify eff so that the set of memory locations decribed after a write to some pointer p is still in the abstract location set of eff. More...
 
effect effect_to_non_pointer_store_independent_effect (effect)
 Modify eff so that the set of memory locations decribed after a write to some non pointer variable is still in the abstract location set of eff. More...
 
effect effect_interference (effect, effect)
 Modifies effect eff1 to make sure that any memory state modification abstracted by eff2 preserves the correctness of eff1: all memory locations included in eff1 at input are included in the memory locations abstracted by the new eff1 after the abstract state transition. More...
 
string action_to_string (action)
 Functions dealing with actions. More...
 
string full_action_to_string (action)
 
string full_action_to_short_string (action)
 
string action_kind_to_string (action_kind)
 
action make_action_write_memory (void)
 To ease the extension of action with action_kind. More...
 
action make_action_read_memory (void)
 
bool action_equal_p (action, action)
 
action_kind action_to_action_kind (action)
 Without the consistency test, this function would certainly be inlined. More...
 
action_kind effect_action_kind (effect)
 
bool store_effect_p (effect)
 
bool environment_effect_p (effect)
 
bool type_declaration_effect_p (effect)
 
bool effects_write_variable_p (list, entity)
 
bool effects_write_p (list)
 
bool effects_read_variable_p (list, entity)
 
bool effects_all_read_p (list)
 Check that all effects in el are read effects. More...
 
bool effect_list_can_be_safely_full_freed_p (list)
 Check if some references might be freed with the effects. More...
 
tag approximation_and (tag, tag)
 tag approximation_and(tag t1, tag t2) input : two approximation tags. More...
 
tag approximation_or (tag, tag)
 tag approximation_or(tag t1, tag t2) input : two approximation tags. More...
 
bool cell_equal_p (cell, cell)
 CELLS. More...
 
bool cell_entity_equal_p (cell, cell)
 
bool points_to_reference_included_p (reference, reference)
 FI->FC/AM: some elements of the lattice must be exploited here... More...
 
bool cell_included_p (cell, cell)
 Check that all memory locations denoted by cell "c1" are included in cell "c2". More...
 
bool cell_equivalent_p (cell, cell)
 Check that memory locations denoted by cell "c1" can be reached by knowing cell "c2" and by using pointer arithmetic or subscripting. More...
 
reference cell_to_reference (cell)
 FI: probably to be moved elsewhere in ri-util. More...
 
bool effect_list_consistent_p (list)
 Debugging. More...
 
bool union_compatible_effects_p (effect, effect)
 DO NOT USE ANYMORE: NOT COMPATIBLE WITH ABSTRACT LOCATIONS. More...
 
entity effect_to_entity (effect)
 Returns the entity corresponding to the mutation. More...
 
bool vect_contains_phi_p (Pvecteur)
 bool vect_contains_phi_p(Pvecteur v) input : a vector output : true if v contains a PHI variable, false otherwise modifies : nothing More...
 
cell points_to_cell_add_field_dimension (cell, entity)
 Functions about points-to cells - There is no cell.c file. More...
 
reference reference_add_field_dimension (reference, entity)
 add a field f as a subscript to a reference r if it is meaningful. More...
 
reference simple_reference_add_field_dimension (reference, entity)
 Do not check anything, just add f as a last subscript. More...
 
void points_to_cell_add_fixed_subscripts (cell, bool)
 Convert a reference to an array into a reference to its first element. More...
 
void points_to_cell_add_zero_subscripts (cell)
 
void points_to_cell_add_zero_subscript (cell)
 
void points_to_cell_complete_with_zero_subscripts (cell)
 
void points_to_cell_add_unbounded_subscripts (cell)
 
void points_to_cell_update_last_subscript (cell, expression)
 Transform reference a[i]...[j] and expression s into reference a[i]..[j+s] if j and s are constant integer expressions, and into reference a[i]..[*] otherwise. More...
 
bool atomic_effect_p (effect)
 
list recursive_cell_to_pointer_cells (cell)
 
list cell_to_pointer_cells (cell)
 If the reference in "c" is not a pointer, see if it can be transformed into a pointer reference by adding subscripts, field subscripts or a combination of both... More...
 
entity entity_all_locations (void)
 anywhere_abstract_locations.c More...
 
entity entity_anywhere_locations (void)
 
bool entity_all_locations_p (entity)
 test if an entity is the top of the lattice More...
 
entity entity_typed_anywhere_locations (type)
 
entity generic_entity_typed_anywhere_locations (type)
 
bool entity_anywhere_locations_p (entity)
 test if an entity is the bottom of the lattice More...
 
bool cell_typed_anywhere_locations_p (cell)
 test if a cell is the bottom of the lattice More...
 
bool reference_typed_anywhere_locations_p (reference)
 test if a reference is the bottom of the lattice More...
 
bool entity_typed_anywhere_locations_p (entity)
 Test if an entity is the bottom of the lattice. More...
 
entity entity_nowhere_locations (void)
 return ANY_MODULE:NOWHERE More...
 
entity entity_typed_nowhere_locations (type)
 
bool entity_nowhere_locations_p (entity)
 test if an entity is the bottom of the lattice More...
 
bool entity_typed_nowhere_locations_p (entity)
 test if an entity is the bottom of the lattice More...
 
entity entity_null_locations (void)
 return TOP-LEVEL:NULL_POINTER The NULL pointer should be a global variable, unique for all modules FI: why isn't it called entity_null_location()? More...
 
bool entity_null_locations_p (entity)
 test if an entity is the NULL POINTER More...
 
entity entity_all_module_locations (entity)
 return m:ANYWHERE Set of all memory locations related to one module. More...
 
bool entity_all_module_locations_p (entity)
 test if an entity is the set of locations defined in a module More...
 
entity entity_all_module_xxx_locations (entity, const char *)
 return m:xxx*ANYWHERE* Generic set of functions for all kinds of areas More...
 
entity entity_all_module_xxx_locations_typed (const char *, const char *, type)
 
bool entity_all_module_xxx_locations_p (entity, string)
 test if an entity is the set of all memory locations in the xxx area of a module. More...
 
entity entity_all_xxx_locations (string)
 return ANY_MODULE:xxx More...
 
entity entity_all_xxx_locations_typed (string, type)
 FI->AM: the predicate entity_all_xxx_locations_typed_p() is missing... More...
 
bool entity_all_xxx_locations_p (entity, string)
 test if an entity is the set of all memory locations in the xxx area of any module. More...
 
entity entity_all_module_heap_locations (entity)
 return m:*HEAP**ANYWHERE More...
 
entity entity_all_module_heap_locations_typed (entity, type)
 
bool entity_all_module_heap_locations_p (entity)
 test if an entity is the a heap area More...
 
entity entity_all_heap_locations (void)
 return ANY_MODULE:HEAP More...
 
bool entity_all_heap_locations_p (entity)
 test if an entity is the set of all heap locations More...
 
entity entity_all_heap_locations_typed (type)
 
entity entity_all_module_stack_locations (entity)
 return m:*STACK**ANYWHERE More...
 
bool entity_all_module_stack_locations_p (entity)
 test if an entity is the a stack area More...
 
entity entity_all_stack_locations (void)
 return ANY_MODULE:STACK More...
 
bool entity_all_stack_locations_p (entity)
 test if an entity is the set of all stack locations More...
 
entity entity_all_module_static_locations (entity)
 return m:*DYNAMIC**ANYWHERE More...
 
bool entity_all_module_static_locations_p (entity)
 test if an entity is the a static area More...
 
entity entity_all_static_locations (void)
 return ANY_MODULE:STATIC More...
 
bool entity_all_static_locations_p (entity)
 test if an entity is the set of all static locations More...
 
entity entity_all_module_dynamic_locations (entity)
 return m:*DYNAMIC**ANYWHERE More...
 
bool entity_all_module_dynamic_locations_p (entity)
 test if an entity is the a dynamic area More...
 
entity entity_all_dynamic_locations (void)
 return ANY_MODULE:DYNAMIC More...
 
bool entity_all_dynamic_locations_p (entity)
 test if an entity is the set of all dynamic locations More...
 
bool entity_stub_sink_p (entity)
 test if an entity is a stub sink for a formal parameter e.g. More...
 
bool stub_entity_of_module_p (entity, entity)
 
bool entity_abstract_location_p (entity)
 
entity variable_to_abstract_location (entity)
 returns the smallest abstract locations containing the location of variable v. More...
 
entity abstract_locations_max (entity, entity)
 eturns the smallest abstract location set greater than or equalt to al1 and al2. More...
 
entity entity_locations_max (entity, entity)
 Here, entity al1 and entity al2 can be program variables. More...
 
entity entity_locations_dereference (entity)
 
void check_abstract_locations (void)
 For debugging the API. More...
 
bool abstract_locations_may_conflict_p (entity, entity)
 Do these two abstract locations MAY share some real memory locations ? More...
 
bool abstract_locations_must_conflict_p (entity, entity)
 
reference make_anywhere_reference (type)
 This function should be located somewhere in effect-util in or near abstract locations. More...
 
cell make_anywhere_cell (type)
 
bool entity_heap_location_p (entity)
 abstract_location.c More...
 
entity entity_flow_or_context_sentitive_heap_location (int, type)
 
bool entity_flow_or_context_sentitive_heap_location_p (entity)
 
type malloc_arg_to_type (expression)
 generate the type of the allocated area from the malloc argument More...
 
entity malloc_type_to_abstract_location (type, sensitivity_information *)
 generate an abstract heap location entity More...
 
entity malloc_to_abstract_location (expression, sensitivity_information *)
 generate an abstract heap location entity More...
 
entity calloc_to_abstract_location (expression, expression, sensitivity_information *)
 generate an abstract heap location entity More...
 
reference original_malloc_to_abstract_location (expression, type, type, expression, entity, statement)
 
sensitivity_information make_sensitivity_information (statement, entity, list)
 
bool pt_to_list_undefined_p (void)
 points_to.c More...
 
void reset_pt_to_list (void)
 
void error_reset_pt_to_list (void)
 
void set_pt_to_list (statement_points_to)
 
statement_points_to get_pt_to_list (void)
 
void init_pt_to_list (void)
 
void close_pt_to_list (void)
 
void store_pt_to_list (statement, points_to_list)
 
void update_pt_to_list (statement, points_to_list)
 
points_to_list load_pt_to_list (statement)
 
points_to_list delete_pt_to_list (statement)
 
bool bound_pt_to_list_p (statement)
 
void store_or_update_pt_to_list (statement, points_to_list)
 
cell make_anywhere_points_to_cell (type)
 Function storing points to information attached to a statement. More...
 
bool formal_parameter_points_to_cell_p (cell)
 
bool stub_points_to_cell_p (cell)
 
bool points_to_cell_in_list_p (cell, list)
 
list merge_points_to_cell_lists (list, list)
 Add in "l1" elements of "l2" that are not yet in "l1". More...
 
bool related_points_to_cell_in_list_p (cell, list)
 Two cells are related if they are based on the same entity. More...
 
bool related_points_to_cells_p (cell, cell)
 
void fprint_points_to_cell (FILE *, cell)
 
void print_points_to_cell (cell)
 Debug: use stderr. More...
 
void print_points_to_cells (list)
 Debug. More...
 
bool field_reference_expression_p (expression)
 Check if expression "e" is a reference to a struct field. More...
 
int points_to_reference_to_final_dimension (reference)
 Compute the number of array subscript at the end of a points_to_reference. More...
 
void points_to_reference_update_final_subscripts (reference, list)
 Substitute the subscripts "sl" in points-to reference "r" just after the last field subscript by "nsl". More...
 
list points_to_reference_to_typed_index (reference, type)
 Look for the index in "r" that corresponds to a pointer of type "t" and return the corresponding element list. More...
 
bool atomic_points_to_cell_p (cell)
 Is it a unique concrete memory location? More...
 
bool generic_atomic_points_to_cell_p (cell, bool)
 Is it a unique concrete memory location? More...
 
bool generic_atomic_points_to_reference_p (reference, bool)
 Is it a unique concrete memory location? More...
 
bool atomic_points_to_reference_p (reference)
 
bool points_to_cells_intersect_p (cell, cell)
 points-to cells use abstract addresses, hence the proper comparison is an intersection. More...
 
cell points_to_cells_minimal_upper_bound (list)
 
entity points_to_cells_minimal_module_upper_bound (list)
 
type points_to_cells_minimal_type_upper_bound (list)
 
reference points_to_cells_minimal_reference_upper_bound (entity, type, list)
 
bool points_to_array_reference_p (reference)
 Is this a reference to an array or a reference to a pointer? This is not linked to the type of the reference, as a reference may be a pointer, such as "a[10]" when "a" is declared int "a[10][20]". More...
 
type points_to_array_reference_to_type (reference)
 If this is an array reference, what is the type of the underlying array type? More...
 
void complete_points_to_reference_with_fixed_subscripts (reference, bool)
 Add a set of zero subscripts to a constant memory path reference "r" by side effect. More...
 
void complete_points_to_reference_with_zero_subscripts (reference)
 
bool cells_must_point_to_null_p (list)
 
bool cells_may_not_point_to_null_p (list)
 
bool cell_points_to_non_null_sink_in_set_p (cell, set)
 A set of functions called cell_points_to_xxxx(cell s, set pts) where set pts is a points-to relation set. More...
 
bool cell_points_to_nowhere_sink_in_set_p (cell, set)
 
bool cell_must_point_to_nowhere_sink_in_set_p (cell, set)
 How are array handled in pts? do we have arcs "a->a"? More...
 
bool cell_points_to_null_sink_in_set_p (cell, set)
 
bool points_to_cell_equal_p (cell, cell)
 
bool similar_arc_in_points_to_set_p (points_to, set, approximation *)
 See if an arc like "spt" exists in set "in", regardless of its approximation. More...
 
list points_to_cell_to_upper_bound_points_to_cells (cell)
 Return a list of cells that are larger than cell "c" in the points-to cell lattice. More...
 
list points_to_cells_to_upper_bound_points_to_cells (list)
 Add to list "l" cells that are upper bound cells of the cells already in list "l" and return list "l". More...
 
bool exact_points_to_subscript_list_p (list)
 See if the subscript list sl is precise, i.e. More...
 
bool compatible_points_to_subscripts_p (expression, expression)
 Two subscript are compatible if they are equal or if one of them is unbounded. More...
 
points_to points_to_with_stripped_sink (points_to, int(*)(void))
 The value of the source can often be expressed with different subscript lists. More...
 
bool recursive_store_independent_points_to_reference_p (type, list)
 
bool store_independent_points_to_reference_p (reference)
 Functions for points-to references, the kind of references used in points-to cells. More...
 
bool constant_points_to_indices_p (list)
 check that the subscript list il is either empty or made of integers or fields. More...
 
bool store_independent_points_to_indices_p (list)
 check that the subscript list il is either empty or made of integers or fields or unbounded entity "*". More...
 
list cell_relations_generic_binary_op (list, list, bool(*)(cell_relation, cell_relation), list(*)(cell_relation, cell_relation), list(*)(cell_relation), list(*)(cell_relation), list(*)(list, list))
 cell_relations.c More...
 
entity undefined_pointer_value_entity (void)
 pointer_values.c More...
 
cell make_undefined_pointer_value_cell (void)
 
bool undefined_pointer_value_entity_p (entity)
 
bool undefined_pointer_value_cell_p (cell)
 
entity null_pointer_value_entity (void)
 
cell make_null_pointer_value_cell (void)
 
bool null_pointer_value_entity_p (entity)
 
bool null_pointer_value_cell_p (cell)
 
bool abstract_pointer_value_entity_p (entity)
 
bool abstract_pointer_value_cell_p (cell)
 
cell_relation make_value_of_pointer_value (cell, cell, tag, descriptor)
 
cell_relation make_address_of_pointer_value (cell, cell, tag, descriptor)
 
bool pv_cells_syntactically_equal_p (cell_relation, cell_relation)
 
bool pv_cells_mergeable_p (cell_relation, cell_relation)
 
int cell_reference_compare (reference *, reference *)
 compare.c More...
 
int cell_compare (cell *, cell *)
 
int effect_compare (effect *, effect *)
 Compares two effects for sorting. More...
 
int compare_effect_reference (effect *, effect *)
 int compare_effect_reference(e1, e2): More...
 
int compare_effect_reference_in_common (effect *, effect *)
 int compare_effect_reference_in_common(e1, e2): More...
 
int pointer_value_compare (cell_relation *, cell_relation *)
 Compares two pointer values for sorting. More...
 
int is_inferior_cell_descriptor_pvarval (Pvecteur *, Pvecteur *)
 weight function for Pvecteur passed as argument to sc_lexicographic_sort in prettyprint functions involving cell descriptors. More...
 
list effect_words_reference (reference)
 prettyprint.c More...
 
string effect_reference_to_string (reference)
 
const char * pips_region_user_name (entity)
 char * pips_region_user_name(entity ent) output : the name of entity. More...
 
list words_fictious_reference (reference)
 To modelize the heap locations we manufacture fictious reference, that triggered a bug when it appears as an argument of entity_user_name(). More...
 
list points_to_words_reference (reference)
 Specific handling of references appearing in points_to. More...
 
list word_points_to (points_to)
 
int points_to_compare_cells (const void *, const void *)
 Comparison of two points-to arcs based on their source and sink nodes. More...
 
list points_to_list_sort (list)
 Allocate a copy of ptl and sort it. More...
 
list words_points_to_list (string, points_to_list)
 
list words_pointer_value (cell_relation)
 
string approximation_to_string (approximation)
 
text text_pointer_value (cell_relation)
 text text_region(effect reg) input : a region output : a text consisting of several lines of commentaries, representing the region modifies : nothing More...
 
text text_pointer_values (list, string)
 
void print_pointer_value (cell_relation)
 
void print_pointer_values (list)
 
entity effect_field_dimension_entity (expression, list)
 type.c More...
 
bool effect_reference_contains_pointer_dimension_p (reference, bool *)
 
bool effect_reference_dereferencing_p (reference, bool *)
 
type cell_reference_to_type (reference, bool *)
 computes the type of a cell reference representing a memory access path. More...
 
type cell_to_type (cell, bool *)
 
type points_to_reference_to_type (reference, bool *)
 FI: I need more generality than is offered by cell_to_type() More...
 
type points_to_expression_to_type (expression, bool *)
 FI: I need more generality than is offered by expression_to_type() because fields are assimilated to subscripts. More...
 
type points_to_expression_to_concrete_type (expression)
 The type returned is stored in a hash-table. More...
 
type points_to_expression_to_pointed_type (expression)
 Return a new allocated type "t" of the address pointed by expression "e", if expression "e" denotes an address. More...
 
type points_to_cell_to_type (cell, bool *)
 FI: I need more generality than is offered by cell_to_type() More...
 
type points_to_cell_to_concrete_type (cell)
 
type points_to_reference_to_concrete_type (reference)
 
bool basic_concrete_types_compatible_for_effects_interprocedural_translation_p (type, type)
 tests if the actual argument type and the formal argument type are compatible with the current state of the interprocedural translation algorithms. More...
 
bool types_compatible_for_effects_interprocedural_translation_p (type, type)
 tests if the actual argument type and the formal argument type are compatible with the current state of the interprocedural translation algorithms. More...
 
void points_to_cell_types_compatibility (cell, cell)
 Make sure that cell l can points towards cell r. More...
 
bool points_to_source_cell_compatible_p (cell)
 
bool points_to_sink_cell_compatible_p (cell)
 
list find_points_to_subscript_for_type (cell, type)
 Find the subscript in the reference of cell "c" that would make the reference type be "t" if the subscript list were truncated just after it. More...
 
bool adapt_reference_to_type (reference, type, int(*)(void))
 FI: a really stupid function... More...
 
bool reference_unbounded_indices_p (reference)
 This function should be at expression.c. More...
 
bool strict_constant_path_p (reference)
 
bool can_be_constant_path_p (reference)
 TODO most of the time return same result that !effect_reference_dereferencing_p for the moment want to test if r can be a constant path for instance a[i] have to return false (something else?) a[0], a[1], i, j, a[*], var points by formal parameter (_p_0, ...), element of strut (s.id, ...), heap element have to return true. More...
 
void set_conflict_testing_properties (void)
 conflicts.c More...
 
bool effects_must_conflict_p (effect, effect)
 Intersection tests. More...
 
bool effects_might_conflict_even_read_only_p (effect, effect)
 Check if two effect might conflict, even if they are read only @description Two effects may conflict if their abstract two location sets has a non-empty intersection. More...
 
bool effects_may_conflict_p (effect, effect)
 Check if two effect may conflict @description Two effects may conflict if their abstract two location sets has a non-empty intersection and if at least one of them is a write. More...
 
bool effects_conflict_p (effect, effect)
 Synonym for effects_may_conflict_p(). More...
 
bool array_references_may_conflict_p (list, list)
 Check if there may be a conflict between two array references. More...
 
bool variable_references_may_conflict_p (entity, list, list)
 FIXME ? More...
 
bool references_may_conflict_p (reference, reference)
 Check if two references may conflict. More...
 
bool references_must_conflict_p (reference, reference)
 Check if two references may conflict. More...
 
bool cells_may_conflict_p (cell, cell)
 Check if two cell may conflict. More...
 
bool points_to_cell_lists_may_conflict_p (list, list)
 Same as above, but for lists. More...
 
bool cells_must_conflict_p (cell, cell)
 Check if two cell must conflict. More...
 
bool points_to_cell_lists_must_conflict_p (list, list)
 Same as above, but for lists. More...
 
bool entities_maymust_conflict_p (entity, entity, bool)
 Check if two entities may or must conflict. More...
 
bool entities_may_conflict_p (entity, entity)
 Check if two entities may conflict. More...
 
bool entities_must_conflict_p (entity, entity)
 Check if two entities must conflict. More...
 
bool first_effect_certainly_includes_second_effect_p (effect, effect)
 tests whether first effect certainly includes second one. More...
 
bool first_exact_scalar_effect_certainly_includes_second_effect_p (effect, effect)
 
bool effect_may_read_or_write_memory_paths_from_entity_p (effect, entity)
 misc functions More...
 
bool effects_may_read_or_write_memory_paths_from_entity_p (list, entity)
 tests whether the input effects list may contain effects with a memory path from the input entity e; this is currently a mere syntactic test. More...
 
bool generic_effects_maymust_read_or_write_scalar_entity_p (list, entity, bool, bool)
 
bool effects_maymust_read_or_write_scalar_entity_p (list, entity, bool)
 
bool concrete_effects_maymust_read_or_write_scalar_entity_p (list, entity, bool)
 
bool effects_may_read_or_write_scalar_entity_p (list, entity)
 check whether scalar entity e may be read or written by effects fx or cannot be accessed at all More...
 
bool concrete_effects_may_read_or_write_scalar_entity_p (list, entity)
 
bool effects_must_read_or_write_scalar_entity_p (list, entity)
 check whether scalar entity e must be read or written by any effect of fx or if it simply might be accessed. More...
 
list effects_entities_which_may_conflict_with_scalar_entity (list, entity)
 
list concrete_effects_entities_which_may_conflict_with_scalar_entity (list, entity)
 
entity make_location_entity (reference)
 locations.c More...
 
entity constant_memory_access_path_to_location_entity (reference)
 A constant memory access path may not be considered. More...
 
bool location_entity_p (entity)
 
bool location_entity_of_module_p (entity, entity)
 
bool array_location_entity_of_module_p (entity, entity)
 Expanded version of location_entity_of_module_p() More...
 
list module_to_analyzed_array_locations (entity)
 m is supposed to be a module entity More...
 

Macro Definition Documentation

◆ ANY_MODULE_NAME

#define ANY_MODULE_NAME   "*ANY_MODULE*"

Warning! Do not modify this file that is automatically generated!

Modify src/Libs/effects-util/effects-util-local.h instead, to add your own modifications. header file built by cproto effects_util-local.h

Definition at line 39 of file effects-util.h.

◆ ANYWHERE_LOCATION

#define ANYWHERE_LOCATION   "*ANYWHERE*"

Definition at line 40 of file effects-util.h.

◆ BETA_PREFIX

#define BETA_PREFIX   "BETA"

Definition at line 52 of file effects-util.h.

◆ cell_relation_approximation_tag

#define cell_relation_approximation_tag (   cr)     approximation_tag(cell_relation_approximation(cr))

Definition at line 188 of file effects-util.h.

◆ cell_relation_exact_p

#define cell_relation_exact_p (   cr)     approximation_tag(cell_relation_approximation(cr))==is_approximation_exact

Definition at line 194 of file effects-util.h.

◆ cell_relation_first_address_of_p

#define cell_relation_first_address_of_p (   cr)     cell_interpretation_address_of_p(interpreted_cell_cell_interpretation(cell_relation_first(cr)))

Definition at line 173 of file effects-util.h.

◆ cell_relation_first_cell

#define cell_relation_first_cell (   cr)     interpreted_cell_cell(cell_relation_first(cr))

Definition at line 164 of file effects-util.h.

◆ cell_relation_first_interpretation_tag

#define cell_relation_first_interpretation_tag (   cr)     cell_interpretation_tag(interpreted_cell_cell_interpretation(cell_relation_first(cr)))

Definition at line 167 of file effects-util.h.

◆ cell_relation_first_value_of_p

#define cell_relation_first_value_of_p (   cr)     cell_interpretation_value_of_p(interpreted_cell_cell_interpretation(cell_relation_first(cr)))

Definition at line 170 of file effects-util.h.

◆ cell_relation_may_p

#define cell_relation_may_p (   cr)     approximation_tag(cell_relation_approximation(cr))==is_approximation_may

Definition at line 191 of file effects-util.h.

◆ cell_relation_second_address_of_p

#define cell_relation_second_address_of_p (   cr)     cell_interpretation_address_of_p(interpreted_cell_cell_interpretation(cell_relation_second(cr)))

Definition at line 185 of file effects-util.h.

◆ cell_relation_second_cell

#define cell_relation_second_cell (   cr)     interpreted_cell_cell(cell_relation_second(cr))

Definition at line 176 of file effects-util.h.

◆ cell_relation_second_interpretation_tag

#define cell_relation_second_interpretation_tag (   cr)     cell_interpretation_tag(interpreted_cell_cell_interpretation(cell_relation_second(cr)))

Definition at line 179 of file effects-util.h.

◆ cell_relation_second_value_of_p

#define cell_relation_second_value_of_p (   cr)     cell_interpretation_value_of_p(interpreted_cell_cell_interpretation(cell_relation_second(cr)))

Definition at line 182 of file effects-util.h.

◆ effect_action_tag

#define effect_action_tag (   eff)    action_tag(effect_action(eff))

Definition at line 60 of file effects-util.h.

◆ effect_any_entity

#define effect_any_entity (   e)    effect_to_entity(e)

some useful SHORTHANDS for EFFECT:

FI: Let's hope this one is not used as lhs!

Definition at line 59 of file effects-util.h.

◆ effect_any_reference

#define effect_any_reference (   e)     (cell_preference_p(effect_cell(e))? preference_reference(cell_preference(effect_cell(e))) : cell_reference(effect_cell(e)))

FI: cannot be used as a left hand side.

Definition at line 139 of file effects-util.h.

◆ effect_approximation_tag

#define effect_approximation_tag (   eff)     approximation_tag(effect_approximation(eff))

Definition at line 61 of file effects-util.h.

◆ effect_exact_p

#define effect_exact_p (   eff)     (approximation_tag(effect_approximation(eff)) ==is_approximation_exact)

Definition at line 86 of file effects-util.h.

◆ effect_may_p

#define effect_may_p (   eff)     (approximation_tag(effect_approximation(eff)) == is_approximation_may)

Definition at line 82 of file effects-util.h.

◆ effect_must_p

#define effect_must_p (   eff)     (approximation_tag(effect_approximation(eff)) == is_approximation_must)

Definition at line 84 of file effects-util.h.

◆ effect_read_p

#define effect_read_p (   eff)    (action_tag(effect_action(eff))==is_action_read)

#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))

The semantics of effects_scalar_p() must be refined. If all the indices are constant expressions, we still have a scalar effect, unless they are later replaced by "*", as is the case currently for summary effects.

Potential bug: eff is evaluated twice. Should be copied in a local variable and braces be used.

Definition at line 80 of file effects-util.h.

◆ effect_reference

#define effect_reference (   e)
Value:
/**DO NOT REMOVE, PREVENT REDEFINITION :)
* use effect_any_reference instead !
*/ \
effect_reference_not_defined_anymore()

FI: it would be useful to assert cell_preference_p(effect_cell(e)), but I do not know how to do it in such a way that it works both for left hand sides and right hand sides using commas.

I definitely remove this one : it is too dangerous. #define effect_reference(e) \ preference_reference(cell_preference(effect_cell(e)))

Definition at line 134 of file effects-util.h.

◆ effect_system

#define effect_system (   e)
Value:
descriptor_convex(effect_descriptor(e)) : SC_UNDEFINED)
#define descriptor_convex_p(x)
Definition: effects.h:599
#define effect_descriptor(x)
Definition: effects.h:646

Definition at line 123 of file effects-util.h.

◆ effect_variable

#define effect_variable (   e)    reference_variable(effect_any_reference(e))

For COMPATIBILITY purpose only - DO NOT USE anymore.

Definition at line 94 of file effects-util.h.

◆ effect_write_p

#define effect_write_p (   eff)    (action_tag(effect_action(eff))==is_action_write)

Definition at line 81 of file effects-util.h.

◆ make_convex_effect

#define make_convex_effect (   reference,
  action,
  approximation,
  system 
)
Value:
make_effect(make_cell(is_reference, (reference)), \
descriptor make_descriptor(enum descriptor_utype tag, void *val)
Definition: effects.c:433
cell make_cell(enum cell_utype tag, void *val)
Definition: effects.c:290
effect make_effect(cell a1, action a2, approximation a3, descriptor a4)
Definition: effects.c:484
@ is_descriptor_convex
Definition: effects.h:575

Definition at line 156 of file effects-util.h.

◆ make_preference_simple_effect

#define make_preference_simple_effect (   reference,
  action,
  approximation 
)
Value:
preference make_preference(reference a1)
Definition: ri.c:1862
@ is_cell_preference
Definition: effects.h:446
@ is_descriptor_none
Definition: effects.h:576
#define UU
Definition: newgen_types.h:98

Definition at line 141 of file effects-util.h.

◆ make_reference_simple_effect

#define make_reference_simple_effect (   reference,
  action,
  approximation 
)

◆ make_simple_effect

#define make_simple_effect (   reference,
  action,
  approximation 
)

◆ NOWHERE_LOCATION

#define NOWHERE_LOCATION   "*NOWHERE*"

Definition at line 41 of file effects-util.h.

◆ NULL_POINTER_NAME

#define NULL_POINTER_NAME   "*NULL*"

Definition at line 43 of file effects-util.h.

◆ NULL_POINTER_VALUE_NAME

#define NULL_POINTER_VALUE_NAME   "*NULL*"

Definition at line 47 of file effects-util.h.

◆ PHI_PREFIX

#define PHI_PREFIX   "PHI"

Definition at line 49 of file effects-util.h.

◆ pips_debug_pv

#define pips_debug_pv (   level,
  message,
  pv 
)
Value:
print_pointer_value(pv);}
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define level
#define ifdebug(n)
Definition: sg.c:47

Definition at line 197 of file effects-util.h.

◆ pips_debug_pvs

#define pips_debug_pvs (   level,
  message,
  l_pv 
)
Value:
print_pointer_values(l_pv);}

Definition at line 201 of file effects-util.h.

◆ PROPER

#define PROPER   true

Definition at line 53 of file effects-util.h.

◆ PSI_PREFIX

#define PSI_PREFIX   "PSI"

Definition at line 50 of file effects-util.h.

◆ RHO_PREFIX

#define RHO_PREFIX   "RHO"

Definition at line 51 of file effects-util.h.

◆ SUMMARY

#define SUMMARY   false

Definition at line 54 of file effects-util.h.

◆ UNDEFINED_LOCATION

#define UNDEFINED_LOCATION   "*UNDEFINED*"

Definition at line 44 of file effects-util.h.

◆ UNDEFINED_POINTER_VALUE_NAME

#define UNDEFINED_POINTER_VALUE_NAME   "*UNDEFINED*"

Definition at line 46 of file effects-util.h.

◆ variable_beta_p

#define variable_beta_p (   e)
Value:
((e)!=(entity)NULL && (e)!=entity_undefined && \
strncmp(entity_name(e), REGIONS_MODULE_NAME, 10)==0 && \
strstr(entity_name(e), BETA_PREFIX) != NULL)
#define BETA_PREFIX
Definition: effects-util.h:52
#define REGIONS_MODULE_NAME
Already defined.
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790

Definition at line 118 of file effects-util.h.

◆ variable_phi_p

#define variable_phi_p (   e)
Value:
((e)!=(entity)NULL && (e)!=entity_undefined && \
strncmp(entity_name(e), REGIONS_MODULE_NAME, 10)==0 && \
strstr(entity_name(e), PHI_PREFIX) != NULL)
#define PHI_PREFIX
Definition: effects-util.h:49

true if e is a phi variable PHI entities have a name like: REGIONS:PHI#, where # is a number.

takes care if TCST and undefined entities, just in case. FC, 09/12/94

Definition at line 103 of file effects-util.h.

◆ variable_psi_p

#define variable_psi_p (   e)
Value:
((e)!=(entity)NULL && (e)!=entity_undefined && \
strncmp(entity_name(e), REGIONS_MODULE_NAME, 10)==0 && \
strstr(entity_name(e), PSI_PREFIX) != NULL)
#define PSI_PREFIX
Definition: effects-util.h:50

Definition at line 108 of file effects-util.h.

◆ variable_rho_p

#define variable_rho_p (   e)
Value:
((e)!=(entity)NULL && (e)!=entity_undefined && \
strncmp(entity_name(e), REGIONS_MODULE_NAME, 10)==0 && \
strstr(entity_name(e), RHO_PREFIX) != NULL)
#define RHO_PREFIX
Definition: effects-util.h:51

Definition at line 113 of file effects-util.h.

Function Documentation

◆ abstract_locations_max()

entity abstract_locations_max ( entity  al1,
entity  al2 
)

eturns the smallest abstract location set greater than or equalt to al1 and al2.

If al1 or al2 is nowhere, then return al2 or al1.

If al1 and al2 are related to the same module, the module can be preserved. Else the anywhere module must be used.

If al1 and al2 are related to the same area, then the area is preserved. Else, the anywhere area is used.

FI: The type part of the abstract location lattice is not implemented... Since the abstract locations are somewhere defined as area, they cannot carry a type. Types are taken care of for heap modelization but not more the abstract locations.

FI: we are in trouble with the NULL pointer... here al1 and al2 must be abstract locations

avoid costly string operations in trivial case

Parameters
al1l1
al2l2

Definition at line 766 of file anywhere_abstract_locations.c.

767 {
769 
770  if (same_entity_p(al1, al2)) /* avoid costly string operations in trivial case */
771  e = al1;
772  else if(!get_bool_property("ALIASING_ACROSS_TYPES")) {
775  if(!type_equal_p(t1, t2))
777  }
778 
779  if(entity_undefined_p(e)) {
780  // FI: the string based tests are not reliable as there is no link
781  // between suffixes and types, even within one module
782  const char* ln1 = entity_local_name(al1);
783  const char* ln2 = entity_local_name(al2);
784  char* mn1 = strdup(entity_module_name(al1));
785  char* mn2 = strdup(entity_module_name(al2));
786  const char* ln;
787  const char* mn;
788  static int mc = 0; // Message count: to avoid multiple repetitions
789 
790  if(mc==0 && !get_bool_property("ALIASING_ACROSS_TYPES")) {
791  //pips_internal_error("Option not implemented yet.");
792  pips_user_warning("property \"ALIASING_ACROSS_TYPES\" is assumed true"
793  " for abstract locations.\n");
794  mc++;
795  }
796 
797  if(strcmp(ln1, ln2)==0)
798  ln = ln1;
799  else
800  ln = ANYWHERE_LOCATION;
801 
802  if(strcmp(mn1, mn2)==0)
803  mn = mn1;
804  else
805  mn = ANY_MODULE_NAME;
806  e = FindEntity(mn, ln);
807 
808  if(true || entity_undefined_p(e)) {
809  if(get_bool_property("ALIASING_ACROSS_TYPES")) {
811  }
812  else {
813  type t1 = entity_type(al1);
814  type t2 = entity_type(al2);
815  if(type_equal_p(t1, t2))
817  else
819  }
820  }
821 
822  free(mn1);free(mn2);
823  }
824  return e;
825 }
entity entity_typed_anywhere_locations(type t)
entity entity_anywhere_locations()
#define ANYWHERE_LOCATION
#define ANY_MODULE_NAME
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void free(void *)
#define pips_user_warning
Definition: misc-local.h:146
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
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
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
bool type_equal_p(type, type)
Definition: type.c:547
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_type(x)
Definition: ri.h:2792
char * strdup()

References ANY_MODULE_NAME, ANYWHERE_LOCATION, entity_anywhere_locations(), entity_basic_concrete_type(), entity_local_name(), entity_module_name(), entity_type, entity_typed_anywhere_locations(), entity_undefined, entity_undefined_p, FindEntity(), free(), get_bool_property(), pips_user_warning, same_entity_p(), strdup(), and type_equal_p().

Referenced by abstract_locations_may_conflict_p(), convex_cells_inclusion_p(), entity_locations_max(), and simple_cells_inclusion_p().

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

◆ abstract_locations_may_conflict_p()

bool abstract_locations_may_conflict_p ( entity  al1,
entity  al2 
)

Do these two abstract locations MAY share some real memory locations ?

Parameters
al1l1
al2l2

Definition at line 989 of file anywhere_abstract_locations.c.

990  {
991  entity mal = abstract_locations_max(al1, al2); // maximal abstraction location
992  bool conflict_p = (mal==al1) || (mal==al2);
993 
994  return conflict_p;
995  }
entity abstract_locations_max(entity al1, entity al2)
eturns the smallest abstract location set greater than or equalt to al1 and al2.

References abstract_locations_max().

Referenced by add_conflicts(), and entities_maymust_conflict_p().

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

◆ abstract_locations_must_conflict_p()

bool abstract_locations_must_conflict_p ( entity  ,
entity   
)

◆ abstract_pointer_value_cell_p()

bool abstract_pointer_value_cell_p ( cell  c)

Definition at line 121 of file pointer_values.c.

122 {
124 }
entity cell_entity(cell)
Definition: effects.c:57
bool abstract_pointer_value_entity_p(entity e)

References abstract_pointer_value_entity_p(), and cell_entity().

Referenced by kill_pointer_value().

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

◆ abstract_pointer_value_entity_p()

bool abstract_pointer_value_entity_p ( entity  e)

Definition at line 115 of file pointer_values.c.

116 {
119 }
bool null_pointer_value_entity_p(entity e)
bool undefined_pointer_value_entity_p(entity e)

References null_pointer_value_entity_p(), and undefined_pointer_value_entity_p().

Referenced by abstract_pointer_value_cell_p().

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

◆ action_equal_p()

bool action_equal_p ( action  a1,
action  a2 
)

action_write_p(a1)

Parameters
a11
a22

Definition at line 1023 of file effects.c.

1024 {
1025  bool equal_p = false;
1026 
1027  if(action_tag(a1)==action_tag(a2)) {
1028  if(action_read_p(a1)) {
1029  action_kind ak1 = action_read(a1);
1030  action_kind ak2 = action_read(a2);
1031 
1032  equal_p = action_kind_tag(ak1)==action_kind_tag(ak2);
1033  }
1034  else /* action_write_p(a1) */ {
1035  action_kind ak1 = action_write(a1);
1036  action_kind ak2 = action_write(a2);
1037 
1038  equal_p = action_kind_tag(ak1)==action_kind_tag(ak2);
1039  }
1040  }
1041  return equal_p;
1042 
1043 }
#define action_write(x)
Definition: effects.h:316
#define action_kind_tag(x)
Definition: effects.h:258
#define action_read(x)
Definition: effects.h:313
#define action_tag(x)
Definition: effects.h:310
#define action_read_p(x)
Definition: effects.h:311

References action_kind_tag, action_read, action_read_p, action_tag, and action_write.

Referenced by combinable_regions_p(), and effect_comparable_p().

+ Here is the caller graph for this function:

◆ action_kind_to_string()

string action_kind_to_string ( action_kind  ak)
Parameters
akk

Definition at line 995 of file effects.c.

996 {
997  string s = string_undefined;
998 
999  if(action_kind_store_p(ak))
1000  s = "S";
1001  else if(action_kind_environment_p(ak))
1002  s = "E";
1003  else if(action_kind_type_declaration_p(ak))
1004  s = "T";
1005  else
1006  pips_internal_error("Unknown action kind.");
1007  return s;
1008 }
#define action_kind_environment_p(x)
Definition: effects.h:262
#define action_kind_store_p(x)
Definition: effects.h:259
#define action_kind_type_declaration_p(x)
Definition: effects.h:265
#define pips_internal_error
Definition: misc-local.h:149
#define string_undefined
Definition: newgen_types.h:40

References action_kind_environment_p, action_kind_store_p, action_kind_type_declaration_p, pips_internal_error, and string_undefined.

◆ action_to_action_kind()

action_kind action_to_action_kind ( action  a)

Without the consistency test, this function would certainly be inlined.

Macros are avoided to simplify debugging and maintenance.

Definition at line 1048 of file effects.c.

1049 {
1050  pips_assert("consistent action kind.",action_read_p(a) || action_write_p(a));
1052  return ak;
1053 }
#define action_write_p(x)
Definition: effects.h:314
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172

References action_read, action_read_p, action_write, action_write_p, and pips_assert.

Referenced by effect_action_kind(), effects_might_conflict_even_read_only_p(), region_sup_difference(), regions_may_convex_hull(), and union_compatible_effects_p().

+ Here is the caller graph for this function:

◆ action_to_string()

string action_to_string ( action  ac)

Functions dealing with actions.

This is correct, but imprecise when action_kinds are taken into account

Parameters
acc

Definition at line 936 of file effects.c.

937 {
938  /* This is correct, but imprecise when action_kinds are taken into
939  account */
940  return action_read_p(ac)? "read" : "write";
941 }

References action_read_p.

◆ adapt_reference_to_type()

bool adapt_reference_to_type ( reference  r,
type  et,
int(*)(void)  line_number_func 
)

FI: a really stupid function...

Why do we add zero subscript right away when building the sink cell to remove them later? Let's now remove the excessive subscripts of "r" with respect to type "at"...

Parameters
ett

Definition at line 1327 of file type.c.

1329 {
1330  bool succeed_p = true;
1331  bool to_be_freed;
1333  type rt = points_to_reference_to_type(r, &to_be_freed);
1335  while(!array_pointer_type_equal_p(at, t) && !ENDP(reference_indices(r))) {
1336  if(to_be_freed) free_type(t);
1337  list sl = reference_indices(r);
1338  list last = gen_last(sl);
1339  expression e = EXPRESSION(CAR(last));
1340  if(expression_field_p(e))
1341  break;
1342  int l1 = (int) gen_length(sl);
1343  gen_remove_once(&sl, (void *) e);
1344  int l2 = (int) gen_length(sl);
1345  if(l1==l2)
1346  pips_internal_error("gen_remove() is ineffective.\n");
1347  reference_indices(r) = sl;
1348  type nrt = points_to_reference_to_type(r, &to_be_freed);
1349  t = compute_basic_concrete_type(nrt);
1350  }
1351  if(!array_pointer_string_type_equal_p(at, t)) {
1352  // FI: this function used to be in library alias_classes
1353  // It should be passed as a functional argument.
1354  //int points_to_context_statement_line_number(void);
1355  pips_user_warning("There may be a typing error at line %d (e.g. improper malloc call).\n Reference \"%s\" with type \"%s\" cannot be adapted to type \"%s\".\n",
1356  // points_to_context_statement_line_number());
1357  (*line_number_func)(),
1361  //pips_internal_error("Cell type mismatch.");
1362  succeed_p = false;
1363  }
1364  if(to_be_freed) free_type(t);
1365  return succeed_p;
1366 }
void free_type(type p)
Definition: ri.c:2658
void const char const char const int
type points_to_reference_to_type(reference ref, bool *to_be_freed)
FI: I need more generality than is offered by cell_to_type()
Definition: type.c:527
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
void gen_remove_once(list *pl, const void *o)
Remove the first occurence of o in list pl:
Definition: list.c:691
size_t gen_length(const list l)
Definition: list.c:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
string reference_to_string(reference r)
Definition: expression.c:87
string type_to_full_string_definition(type t)
Provide a full ASCII description of type "t".
Definition: type.c:45
bool expression_field_p(expression e)
The expression is of kind "s.a", where "s" is a struct and a "a" field.
Definition: expression.c:491
bool array_pointer_string_type_equal_p(type t1, type t2)
Assume that a pointer to type x is equal to a 1-D array of x.
Definition: type.c:658
bool array_pointer_type_equal_p(type t1, type t2)
assume that a pointer to type x is equal to a 1-D array of x
Definition: type.c:609
type compute_basic_concrete_type(type t)
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 EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References array_pointer_string_type_equal_p(), array_pointer_type_equal_p(), CAR, compute_basic_concrete_type(), ENDP, EXPRESSION, expression_field_p(), free_type(), gen_last(), gen_length(), gen_remove_once(), int, pips_internal_error, pips_user_warning, points_to_reference_to_type(), reference_indices, reference_to_string(), and type_to_full_string_definition().

Referenced by dereferencing_subscript_to_points_to(), expression_to_points_to_cells(), filter_formal_context_according_to_actual_context(), new_filter_formal_context_according_to_actual_context(), points_to_with_stripped_sink(), process_casted_sinks(), process_casted_sources(), subscript_to_points_to_sinks(), and subscripted_reference_to_points_to().

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

◆ all_heap_locations_cell_p()

bool all_heap_locations_cell_p ( cell  c)

Definition at line 432 of file effects.c.

433 {
434  bool heap_p;
436  entity v = reference_variable(r);
437 
438  heap_p = entity_all_heap_locations_p(v);
439 
440  return heap_p;
441 }
reference cell_any_reference(cell c)
API for reference.
Definition: effects.c:77
bool entity_all_heap_locations_p(entity e)
test if an entity is the set of all heap locations
#define reference_variable(x)
Definition: ri.h:2326

References cell_any_reference(), entity_all_heap_locations_p(), and reference_variable.

Referenced by points_to_cell_types_compatibility(), points_to_function_projection(), and subscript_to_points_to_sinks().

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

◆ any_anywhere_effect_p()

bool any_anywhere_effect_p ( effect  e)

Is it a typed or untyped anywhere effect?

Definition at line 358 of file effects.c.

359 {
360  return generic_anywhere_effect_p(e, 2);
361 }
static bool generic_anywhere_effect_p(effect e, int kind)
Is it an anywhere effect (kind=0)? a typed anywhere effect (kind=1) ? or any kind of anywhere effect ...
Definition: effects.c:333

References generic_anywhere_effect_p().

+ Here is the call graph for this function:

◆ anywhere_cell_p()

bool anywhere_cell_p ( cell  c)

◆ anywhere_effect()

effect anywhere_effect ( action  ac)

Anywhere effect: an effect which can be related to any location of any areas.

Allocate a new anywhere effect, and the anywhere entity on demand which may not be best if we want to express it's aliasing with all module areas. In the later case, the anywhere entity should be generated by bootstrap and be updated each time new areas are declared by the parsers. I do not use a persistant anywhere reference to avoid trouble with convex-effect nypassing of the persistant pointer.

Action a is integrated in the new effect (aliasing). NOT GENERIC AT ALL. USE make_anywhere_effect INSTEAD (BC).

Parameters
acc

Definition at line 317 of file effects.c.

318 {
319  entity anywhere = entity_all_locations();
320  effect any = effect_undefined;
321 
323  ac,
326 
327  return any;
328 }
cell make_cell_reference(reference _field_)
Definition: effects.c:293
approximation make_approximation_may(void)
Definition: effects.c:179
descriptor make_descriptor_none(void)
Definition: effects.c:442
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
entity entity_all_locations()
eturn ANY_MODULE:ANYWHERE (the top of the lattice)
#define effect_undefined
Definition: effects.h:614
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47

References effect_undefined, entity_all_locations(), make_approximation_may(), make_cell_reference(), make_descriptor_none(), make_effect(), make_reference(), and NIL.

Referenced by effect_to_pointer_store_independent_effect(), and effect_to_store_independent().

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

◆ anywhere_effect_p()

◆ anywhere_reference_p()

bool anywhere_reference_p ( reference  r)

Definition at line 378 of file effects.c.

379 {
380  bool anywhere_p;
381  entity v = reference_variable(r);
382 
383  anywhere_p = entity_all_locations_p(v);
384 
385  return anywhere_p;
386 }

References entity_all_locations_p(), and reference_variable.

Referenced by any_assign_to_transformer().

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

◆ approximation_and()

tag approximation_and ( tag  t1,
tag  t2 
)

tag approximation_and(tag t1, tag t2) input : two approximation tags.

output : the tag representing their "logical and", assuming that must = true and may = false. modifies : nothing

Parameters
t11
t22

Definition at line 1198 of file effects.c.

1199 {
1200  if ((t1 == is_approximation_exact) && (t2 == is_approximation_exact))
1201  return(is_approximation_exact);
1202  else
1203  return(is_approximation_may);
1204 }
@ is_approximation_may
Definition: effects.h:341
@ is_approximation_exact
Definition: effects.h:343

References is_approximation_exact, and is_approximation_may.

Referenced by effect_may_union(), effect_must_union(), make_simple_pv_from_simple_effects(), region_intersection(), region_union(), and regions_may_convex_hull().

+ Here is the caller graph for this function:

◆ approximation_or()

tag approximation_or ( tag  t1,
tag  t2 
)

tag approximation_or(tag t1, tag t2) input : two approximation tags.

output : the tag representing their "logical or", assuming that must = true and may = false. modifies : nothing

Parameters
t11
t22

Definition at line 1213 of file effects.c.

1214 {
1215  if ((t1 == is_approximation_exact) || (t2 == is_approximation_exact))
1216  return(is_approximation_exact);
1217  else
1218  return(is_approximation_may);
1219 }

References is_approximation_exact, and is_approximation_may.

Referenced by effect_must_union(), region_union(), and regions_must_convex_hull().

+ Here is the caller graph for this function:

◆ approximation_to_string()

string approximation_to_string ( approximation  a)

Definition at line 458 of file prettyprint.c.

459 {
460  string as = string_undefined;
461  if(approximation_may_p(a))
462  as = "may";
463  else if(approximation_must_p(a))
464  as = "must"; // could be "exact"
465  else if(approximation_exact_p(a))
466  as = "exact";
467  else
468  pips_internal_error("Unknown approximation tag.\n");
469  return as;
470 }
#define approximation_exact_p(x)
Definition: effects.h:369
#define approximation_may_p(x)
Definition: effects.h:363
#define approximation_must_p(x)
Definition: effects.h:366

References approximation_exact_p, approximation_may_p, approximation_must_p, pips_internal_error, and string_undefined.

Referenced by print_or_dump_points_to().

+ Here is the caller graph for this function:

◆ array_location_entity_of_module_p()

bool array_location_entity_of_module_p ( entity  le,
entity  m 
)

Expanded version of location_entity_of_module_p()

Parameters
lee

Definition at line 374 of file locations.c.

375 {
376  bool location_p = false;
377  if(!entity_undefined_p(le)) {
378  value v = entity_initial(le);
379  if(!value_undefined_p(v))
380  if(value_reference_p(v))
381  // FI: could be checked with a pointer equality via the storage field
382  if(strcmp(entity_module_name(le), entity_user_name(m))==0) {
383  reference r = value_reference(v);
384  entity a = reference_variable(r);
386  location_p = array_type_p(t);
387  }
388  }
389  return location_p;
390 }
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
bool array_type_p(type)
Definition: type.c:2942
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_reference(x)
Definition: ri.h:3085
#define value_reference_p(x)
Definition: ri.h:3083
#define entity_initial(x)
Definition: ri.h:2796

References array_type_p(), entity_basic_concrete_type(), entity_initial, entity_module_name(), entity_undefined_p, entity_user_name(), reference_variable, value_reference, value_reference_p, and value_undefined_p.

Referenced by module_to_analyzed_array_locations().

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

◆ atomic_effect_p()

bool atomic_effect_p ( effect  e)

Maybe it is an effect on a structure field

Definition at line 1668 of file effects.c.

1669 {
1670  bool atomic_p = effect_scalar_p(e);
1671  if(!atomic_p) {
1672  /* Maybe it is an effect on a structure field */
1673  cell c = effect_cell(e);
1674  atomic_p = atomic_points_to_cell_p(c);
1675  }
1676  return atomic_p;
1677 }
bool effect_scalar_p(effect eff)
Definition: effects.c:567
bool atomic_points_to_cell_p(cell)
Is it a unique concrete memory location?
Definition: points_to.c:423
#define effect_cell(x)
Definition: effects.h:640

References atomic_points_to_cell_p(), effect_cell, and effect_scalar_p().

+ Here is the call graph for this function:

◆ atomic_points_to_cell_p()

bool atomic_points_to_cell_p ( cell  c)

Is it a unique concrete memory location?

Plus NULL? No doubt about the value of the pointer...

Plus undefined? No doubt about the indeterminate value of the pointer according to C standard...

Definition at line 423 of file points_to.c.

424 {
426  bool atomic_p = null_cell_p(c)
427  || nowhere_cell_p(c) // FI: added for EffectsWithPointsTo/call30.c
429 
430  // FI: atomic_p should be false for all abstract locations
431  // This is dealt with by atomic_points_to_reference_p()
432  /*
433  if(atomic_p && (heap_cell_p(c) || all_heap_locations_cell_p(c)))
434  atomic_p = false;
435 
436  if(atomic_p) {
437  atomic_p = !cell_abstract_location_p(c);
438  }
439  */
440 
441  return atomic_p;
442 }
bool atomic_points_to_reference_p(reference r)
Definition: points_to.c:519
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
bool nowhere_cell_p(cell)
Target of an undefined pointer.
Definition: effects.c:455
bool null_cell_p(cell)
Definition: effects.c:466

References atomic_points_to_reference_p(), cell_any_reference(), nowhere_cell_p(), and null_cell_p().

Referenced by atomic_effect_p(), compute_points_to_gen_set(), compute_points_to_kill_set(), equal_condition_to_points_to(), freed_list_to_points_to(), non_equal_condition_to_points_to(), null_equal_condition_to_points_to(), and points_to_function_projection().

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

◆ atomic_points_to_reference_p()

bool atomic_points_to_reference_p ( reference  r)

Definition at line 519 of file points_to.c.

520 {
521  return generic_atomic_points_to_reference_p(r, true);
522 }
bool generic_atomic_points_to_reference_p(reference r, bool strict_p)
Is it a unique concrete memory location?
Definition: points_to.c:489

References generic_atomic_points_to_reference_p().

Referenced by atomic_points_to_cell_p(), and substitute_stubs_in_transformer().

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

◆ basic_concrete_types_compatible_for_effects_interprocedural_translation_p()

bool basic_concrete_types_compatible_for_effects_interprocedural_translation_p ( type  real_ct,
type  formal_ct 
)

tests if the actual argument type and the formal argument type are compatible with the current state of the interprocedural translation algorithms.

Input types are

See also
basic_concrete_type .

safe default result

easiest case

we do not take care of array dimension sizes

well, basic_equal_strict_p is at the same time too restrictive for derived and too optimistic for pointers and arrays because dimensions are skipped

skip same number of array and pointer dimensions until we reach the ultimate basic or there are no more corresponding dimensions

we have a void * as actual argument

translation cannot be accurate

we are sure here that gen_length(formal_dims) != 0

we have a void * as actual argument

translation cannot be accurate

we are sure here that gen_length(real_dims) != 0

store types and not bct becasue bct cannot be equal, since a new type is generated each time. We really need a global table for bcts

It should be a strict type equality here, but I don't think type_equal_p is very robust when types are declared in headers

Parameters
real_cteal_ct
formal_ctormal_ct

Definition at line 699 of file type.c.

700 {
701  static list real_structured_types = NIL;
702  static list formal_structured_types = NIL;
703 
704  pips_debug(8,"real_ct : %s \t formal_ct: %s\n",
705  string_of_type(real_ct),
706  string_of_type(formal_ct));
707 
708  bool result = false; /* safe default result */
709  /* easiest case */
710  if (real_ct == formal_ct)
711  {
712  pips_debug(8, "types are equal\n");
713  result = true;
714  }
715 
716  else if (type_tag(real_ct) != type_tag(formal_ct))
717  {
718  pips_debug(8, "not same type tags\n");
719  result = false;
720  }
721 
722  else
723  {
724  switch(type_tag(real_ct))
725  {
726  case is_type_void:
727  result = true;
728  break;
729  case is_type_variable:
730  {
731  pips_debug(8, "variable case\n");
732  basic real_b = variable_basic(type_variable(real_ct));
733  list real_dims = variable_dimensions(type_variable(real_ct));
734  basic formal_b = variable_basic(type_variable(formal_ct));
735  list formal_dims = variable_dimensions(type_variable(formal_ct));
736 
737  bool finished = false;
738  /* we do not take care of array dimension sizes */
739  while (! finished)
740  {
741  if (gen_length(real_dims) == gen_length(formal_dims))
742  {
743  /* well, basic_equal_strict_p is at the same time too restrictive
744  for derived and too optimistic for pointers and arrays because
745  dimensions are skipped
746  */
747  if (basic_pointer_p(real_b) && basic_pointer_p(formal_b))
748  {
749  pips_debug(8, "pointer case\n");
750  result =
752  (basic_pointer(real_b), basic_pointer(formal_b));
753  }
754  else if (basic_derived_p(real_b) && basic_derived_p(formal_b))
755  {
756  entity real_basic_e = basic_derived(real_b);
757  entity formal_basic_e = basic_derived(formal_b);
758  pips_debug(8, "derived case, real: %s, formal: %s\n",
759  entity_name(real_basic_e),
760  entity_name(formal_basic_e));
761  if (same_entity_p(real_basic_e, formal_basic_e))
762  {
763  pips_debug(8, "same entities (1) \n");
764  result = true;
765  }
766  else
767  {
768  type formal_dt = entity_type(formal_basic_e);
769  type real_dt = entity_type(real_basic_e);
770 
771  void * found_formal_t = (type) gen_find_eq(formal_dt,formal_structured_types);
772  void * found_real_t = (type) gen_find_eq(real_dt,real_structured_types);
773 
774  if (!gen_chunk_undefined_p(found_formal_t))
775  {
776  pips_debug(8, "types already encountered (1) \n");
777  result = gen_position(found_formal_t, formal_structured_types)
778  == gen_position(found_real_t, real_structured_types);
779  }
780  else
781  {
782  pips_debug(8, "types not encountered (1) \n");
783  formal_structured_types = gen_type_cons(formal_dt, formal_structured_types);
784  real_structured_types = gen_type_cons(real_dt, real_structured_types);
786  list old_formal_structured_types = formal_structured_types;
787  list old_real_structured_types = real_structured_types;
788  POP(formal_structured_types);
789  POP(real_structured_types);
790  CDR(old_formal_structured_types) = NIL;
791  CDR(old_real_structured_types) = NIL;
792  gen_free_list(old_formal_structured_types);
793  gen_free_list(old_real_structured_types);
794  }
795  }
796  }
797  else
798  result = basic_equal_p(real_b, formal_b);
799  finished = true;
800  }
801  else
802  {
803  /* skip same number of array and pointer dimensions until we reach the
804  ultimate basic or there are no more corresponding dimensions
805  */
806  if (basic_pointer_p(real_b) && gen_length(real_dims) == 0)
807  {
808  real_ct = basic_pointer(real_b);
809  if (type_void_p(real_ct))
810  {
811  /* we have a void * as actual argument */
812  /* translation cannot be accurate */
813  finished = true;
814  }
815  else if (type_variable_p(real_ct))
816  {
817  real_b = variable_basic(type_variable(real_ct));
818  real_dims = variable_dimensions(type_variable(real_ct));
819  formal_dims = CDR(formal_dims); /* we are sure here that gen_length(formal_dims) != 0*/
820  }
821  else
822  finished = true;
823  }
824  else if (basic_pointer_p(formal_b) && gen_length(formal_dims) == 0)
825  {
826  formal_ct = basic_pointer(formal_b);
827  if (type_void_p(formal_ct))
828  {
829  /* we have a void * as actual argument */
830  /* translation cannot be accurate */
831  finished = true;
832  }
833  else if (type_variable_p(formal_ct))
834  {
835  formal_b = variable_basic(type_variable(formal_ct));
836  formal_dims = variable_dimensions(type_variable(formal_ct));
837  real_dims = CDR(real_dims); /* we are sure here that gen_length(real_dims) != 0*/
838  }
839  else
840  finished = true;
841  }
842  else
843  finished = true;
844  }
845  }
846  }
847  break;
848  case is_type_struct:
849  case is_type_union:
850  case is_type_enum:
851  pips_debug(8, "struct, union or enum case\n");
852  list real_fields = type_fields(real_ct);
853  list formal_fields = type_fields(formal_ct);
854  if (gen_length(real_fields) == gen_length(formal_fields))
855  {
856  result = true;
857  while(result && !ENDP(real_fields))
858  {
859  entity real_fe = ENTITY(CAR(real_fields));
860  entity formal_fe = ENTITY(CAR(formal_fields));
861  pips_debug(8, "fields, real: %s, formal: %s\n",
862  entity_name(real_fe),
863  entity_name(formal_fe));
864 
865  if (same_entity_p(real_fe, formal_fe))
866  {
867  pips_debug(8, "same entities (2)\n");
868  result = true;
869  }
870  else
871  {
872  type real_ft = entity_type(real_fe);
873  type formal_ft = entity_type(formal_fe);
874 
875  void * found_formal_ft = (type) gen_find_eq(formal_ft,formal_structured_types);
876  void * found_real_ft = (type) gen_find_eq(real_ft,real_structured_types);
877 
878  if (!gen_chunk_undefined_p(found_formal_ft))
879  {
880  pips_debug(8, "types already encountered (2)\n");
881  result = gen_position(found_formal_ft, formal_structured_types)
882  == gen_position(found_real_ft, real_structured_types);
883  }
884  else
885  {
886  pips_debug(8, "types not encountered (2)\n");
887  /* store types and not bct becasue bct cannot be equal,
888  since a new type is generated each time.
889  We really need a global table for bcts */
890  formal_structured_types = gen_type_cons(formal_ft, formal_structured_types);
891  real_structured_types = gen_type_cons(real_ft, real_structured_types);
892  type real_fbct = entity_basic_concrete_type(real_fe);
893  type formal_fbct = entity_basic_concrete_type(formal_fe);
894  /* It should be a strict type equality here, but I don't think type_equal_p
895  is very robust when types are declared in headers
896  */
897  result =
899  (real_fbct, formal_fbct);
900 
901  list old_formal_structured_types = formal_structured_types;
902  list old_real_structured_types = real_structured_types;
903  POP(formal_structured_types);
904  POP(real_structured_types);
905  CDR(old_formal_structured_types) = NIL;
906  CDR(old_real_structured_types) = NIL;
907  gen_free_list(old_formal_structured_types);
908  gen_free_list(old_real_structured_types);
909  }
910  }
911  POP(real_fields);
912  POP(formal_fields);
913  }
914  }
915  break;
916  case is_type_functional:
917  pips_debug(8, "functional case\n");
918  result = true;
919  break;
920  default:
921  pips_internal_error("unexpected function argument type: %s\n", type_to_string(real_ct) );
922  }
923  }
924  pips_debug(8, "returning %s\n", result? "true":"false");
925  return result;
926 }
list gen_type_cons(type p, list l)
Definition: ri.c:2671
struct _newgen_struct_type_ * type
bool basic_concrete_types_compatible_for_effects_interprocedural_translation_p(type real_ct, type formal_ct)
tests if the actual argument type and the formal argument type are compatible with the current state ...
Definition: type.c:699
#define gen_chunk_undefined_p(c)
Definition: genC.h:75
int gen_position(const void *item, const list l)
Element ranks are strictly positive as for first, second, and so on.
Definition: list.c:995
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422
string string_of_type(const type t)
Definition: type.c:56
list type_fields(type t)
Definition: type.c:3073
bool basic_equal_p(basic b1, basic b2)
Definition: type.c:927
type entity_basic_concrete_type(entity e)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
string type_to_string(const type t)
type.c
Definition: type.c:51
#define basic_pointer(x)
Definition: ri.h:637
#define basic_derived(x)
Definition: ri.h:640
#define type_tag(x)
Definition: ri.h:2940
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#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 type_void_p(x)
Definition: ri.h:2959
#define variable_dimensions(x)
Definition: ri.h:3122
@ is_type_void
Definition: ri.h:2904
@ is_type_enum
Definition: ri.h:2907
@ is_type_functional
Definition: ri.h:2901
@ is_type_variable
Definition: ri.h:2900
@ is_type_union
Definition: ri.h:2906
@ is_type_struct
Definition: ri.h:2905
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120

References basic_concrete_types_compatible_for_effects_interprocedural_translation_p(), basic_derived, basic_derived_p, basic_equal_p(), basic_pointer, basic_pointer_p, CAR, CDR, ENDP, ENTITY, entity_basic_concrete_type(), entity_name, entity_type, gen_chunk_undefined_p, gen_find_eq(), gen_free_list(), gen_length(), gen_position(), gen_type_cons(), is_type_enum, is_type_functional, is_type_struct, is_type_union, is_type_variable, is_type_void, NIL, pips_debug, pips_internal_error, POP, same_entity_p(), string_of_type(), type_fields(), type_tag, type_to_string(), type_variable, type_variable_p, type_void_p, variable_basic, and variable_dimensions.

Referenced by basic_concrete_types_compatible_for_effects_interprocedural_translation_p(), c_convex_effects_on_actual_parameter_forward_translation(), and types_compatible_for_effects_interprocedural_translation_p().

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

◆ bound_pt_to_list_p()

bool bound_pt_to_list_p ( statement  )

Referenced by statement_to_points_to().

+ Here is the caller graph for this function:

◆ calloc_to_abstract_location()

entity calloc_to_abstract_location ( expression  n,
expression  size,
sensitivity_information psi 
)

generate an abstract heap location entity

Parameters
nis the first argument expression of the call to calloc
sizeis the second argument expression of the call to calloc
psiis a pointer towards a structure which contains context and/or flow sensitivity information
Returns
an abstract heap location entity
Parameters
sizeize
psisi

Definition at line 414 of file abstract_location.c.

416 {
417  expression malloc_exp = make_op_exp("*",
418  copy_expression(n),
419  copy_expression(size));
420  entity e = malloc_to_abstract_location(malloc_exp, psi);
421  free_expression(malloc_exp);
422  return(e);
423 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
void free_expression(expression p)
Definition: ri.c:853
entity malloc_to_abstract_location(expression malloc_exp, sensitivity_information *psi)
generate an abstract heap location entity
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012

References copy_expression(), free_expression(), make_op_exp(), and malloc_to_abstract_location().

+ Here is the call graph for this function:

◆ can_be_constant_path_p()

bool can_be_constant_path_p ( reference  r)

TODO most of the time return same result that !effect_reference_dereferencing_p for the moment want to test if r can be a constant path for instance a[i] have to return false (something else?) a[0], a[1], i, j, a[*], var points by formal parameter (_p_0, ...), element of strut (s.id, ...), heap element have to return true.

  • !effect_reference_dereferencing_p(r, &exact_p) can return true when it's not a constant path like a[i] (a[i] and not a[*]) can make a side effect for the declaration of variable in parameter (only?), don't know why for instance with Semantics-New/Pointer.sub/memcopy01 void memcopy01([...], char dst[size]) --> void memcopy01([...], char dst[i])
  • store_independent_reference_p(r) can return false for some cp like a[0], can't permit to treat the array return false for the structure too, can't permit to treat the struct can return true for i, j, ... that can be a constant path but not strictly a constant path param r reference to analyze to see if it's a constant path return true if r can be constant path

This function is not used by the points-to analysis, but by semantics

Definition at line 1492 of file type.c.

1493 {
1494  bool constant_path = true;
1495 
1496  if (strict_constant_path_p(r))
1497  constant_path = true;
1498  else {
1499  bool exact_p = true;
1500  if (!effect_reference_dereferencing_p(r, &exact_p)) {
1501  constant_path = true;
1502  }
1503  else {
1504  constant_path = false;
1505  }
1506  }
1507 
1508  return constant_path;
1509 }
bool strict_constant_path_p(reference r)
Definition: type.c:1407
bool effect_reference_dereferencing_p(reference ref, bool *exact_p)
Definition: type.c:233

References effect_reference_dereferencing_p(), and strict_constant_path_p().

Referenced by update_reflhs_with_rhs_to_transformer().

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

◆ cell_abstract_location_p()

bool cell_abstract_location_p ( cell  c)

Definition at line 273 of file effects.c.

274 {
275  pips_assert("cell is not a GAP", !cell_gap_p(c));
276 
278 }
bool entity_abstract_location_p(entity al)
#define cell_gap_p(x)
Definition: effects.h:473

References cell_any_reference(), cell_gap_p, entity_abstract_location_p(), pips_assert, and reference_variable.

Referenced by cells_to_read_or_write_effects(), convex_cells_inclusion_p(), convex_cells_intersection_p(), effect_abstract_location_p(), simple_cells_inclusion_p(), simple_cells_intersection_p(), and upgrade_approximations_in_points_to_set().

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

◆ cell_any_reference()

reference cell_any_reference ( cell  c)

API for reference.

Definition at line 77 of file effects.c.

78 {
79  if (cell_gap_p(c)) return reference_undefined;
80 
81  return (cell_reference_p(c)) ? cell_reference(c) :
83 }
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define cell_reference_p(x)
Definition: effects.h:467
#define reference_undefined
Definition: ri.h:2302
#define preference_reference(x)
Definition: ri.h:2102

References cell_gap_p, cell_preference, cell_reference, cell_reference_p, preference_reference, and reference_undefined.

Referenced by aliased_translation_p(), all_heap_locations_cell_p(), any_assign_to_transformer(), anywhere_cell_p(), anywhere_source_to_sinks(), array_formal_parameter_to_stub_points_to(), atomic_constant_path_p(), atomic_points_to_cell_p(), binary_intrinsic_call_to_points_to_sinks(), cell_abstract_location_p(), cell_entity(), cell_equivalent_p(), cell_included_p(), cell_indices(), cell_is_xxx_p(), cell_to_pointer_cells(), cell_typed_anywhere_locations_p(), cells_to_read_or_write_effects(), check_type_of_points_to_cells(), compute_points_to_binded_set(), compute_points_to_gen_set(), compute_points_to_kill_set(), consistent_points_to_arc_p(), convex_cell_preceding_p(), create_pointer_to_array_stub_points_to(), create_stub_points_to(), dereferencing_subscript_to_points_to(), dereferencing_to_sinks(), derived_formal_parameter_to_stub_points_to(), equal_must_vreference(), expand_points_to_domain(), expression_to_points_to_cells(), extended_source_to_sinks(), filter_formal_context_according_to_actual_context(), filter_formal_out_context_according_to_formal_in_context(), find_points_to_subscript_for_type(), formal_parameter_points_to_cell_p(), formal_source_to_sinks(), fprint_points_to_cell(), freeable_points_to_cells(), freed_list_to_points_to(), gen_may_constant_paths(), gen_may_set(), gen_must_constant_paths(), gen_must_set(), generic_apply_effects_to_transformer(), generic_atomic_points_to_cell_p(), generic_points_to_cells_translation(), generic_points_to_set_to_stub_cell_list(), generic_remove_unreachable_vertices_in_points_to_graph(), generic_stub_source_to_sinks(), generic_transform_sink_cells_from_matching_list(), generic_unary_operation_to_transformer(), global_source_to_sinks(), heap_cell_p(), io_cell_p(), k_limit_points_to(), lhs_expression_to_transformer(), list_assignment_to_points_to(), malloc_to_points_to_sinks(), max_module(), module_to_value_mappings(), new_array_elements_backward_substitution_in_transformer(), new_array_elements_forward_substitution_in_transformer(), new_filter_formal_context_according_to_actual_context(), nowhere_cell_p(), nowhere_source_to_sinks(), null_cell_p(), null_source_to_sinks(), offset_cell(), offset_points_to_cell(), opkill_may_constant_path(), opkill_may_module(), opkill_may_name(), opkill_may_vreference(), opkill_must_constant_path(), opkill_must_module(), opkill_must_name(), opkill_must_reference(), opkill_must_vreference(), pointer_arithmetic_to_points_to(), pointer_source_to_sinks(), pointer_subscript_to_expression(), points_to_anywhere_typed(), points_to_binding(), points_to_cell_add_fixed_subscripts(), points_to_cell_add_zero_subscript(), points_to_cell_complete_with_zero_subscripts(), points_to_cell_equal_p(), points_to_cell_to_number_of_unbounded_dimensions(), points_to_cell_to_string(), points_to_cell_to_type(), points_to_cell_to_upper_bound_points_to_cells(), points_to_cell_translation(), points_to_cell_types_compatibility(), points_to_cell_update_last_subscript(), points_to_cells_intersect_p(), points_to_function_projection(), points_to_reference_to_translation(), points_to_set_block_projection(), points_to_set_sharing_p(), points_to_source_projection(), points_to_source_to_translations(), points_to_translation_mapping_is_typed_p(), points_to_translation_of_formal_parameters(), points_to_with_stripped_sink(), potential_to_effective_memory_leaks(), print_points_to_cells(), process_casted_sinks(), process_casted_sources(), pv_cells_mergeable_p(), reduce_cell_to_pointer_type(), reference_to_points_to_translations(), refine_points_to_cell_subscripts(), related_points_to_cell_in_list_p(), related_points_to_cells_p(), relevant_translation_pair_p(), simple_cell_preceding_p(), simple_cell_to_convex_cell_conversion(), simple_pv_may_union(), simple_pv_must_union(), sinks_fully_matches_source_p(), source_to_sinks(), struct_assignment_to_points_to(), struct_initialization_to_points_to(), struct_reference_assignment_or_equality_to_transformer(), struct_variable_to_pointer_subscripts(), stub_points_to_cell_p(), stub_source_to_sinks(), subscript_to_points_to_sinks(), subscripted_reference_to_points_to(), substitute_stubs_in_transformer(), substitute_stubs_in_transformer_with_translation_binding(), type_compatible_super_cell(), type_compatible_with_points_to_cell_p(), typedef_formal_parameter_to_stub_points_to(), unique_location_cell_p(), user_call_to_points_to_sinks(), and variable_to_sinks().

◆ cell_compare()

int cell_compare ( cell c1,
cell c2 
)
Parameters
c11
c22

Definition at line 168 of file compare.c.

169 {
170  pips_assert("gaps not handled yet (ppv1 first)", !cell_gap_p(*c1));
171  pips_assert("gaps not handled yet (ppv2 first)", !cell_gap_p(*c2));
172 
174 
175 }
int cell_reference_compare(reference *pr1, reference *pr2)
compare.c
Definition: compare.c:54

References cell_gap_p, cell_reference, cell_reference_compare(), and pips_assert.

Referenced by effect_compare(), pointer_value_compare(), pv_cells_mergeable_p(), pv_cells_syntactically_equal_p(), pvs_union_combinable_p(), simple_pv_may_union(), and simple_pv_must_union().

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

◆ cell_entity()

◆ cell_entity_equal_p()

bool cell_entity_equal_p ( cell  c1,
cell  c2 
)

Has to be extended for GAPs

Parameters
c11
c22

Definition at line 1234 of file effects.c.

1235 {
1236  /* Has to be extended for GAPs */
1237  reference r1 = cell_to_reference(c1);
1238  reference r2 = cell_to_reference(c2);
1239  return reference_variable(r1)==reference_variable(r2);
1240 }
reference cell_to_reference(cell c)
FI: probably to be moved elsewhere in ri-util.
Definition: effects.c:1326

References cell_to_reference(), and reference_variable.

Referenced by points_to_binding().

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

◆ cell_equal_p()

bool cell_equal_p ( cell  c1,
cell  c2 
)

◆ cell_equivalent_p()

bool cell_equivalent_p ( cell  c1,
cell  c2 
)

Check that memory locations denoted by cell "c1" can be reached by knowing cell "c2" and by using pointer arithmetic or subscripting.

In other words, the two cells only differ by their subscripts... Which might be reducible to "based on the same entity".

FI: experimental...

Has to be extended for GAPs

Parameters
c11
c22

Definition at line 1311 of file effects.c.

1312 {
1313  /* Has to be extended for GAPs */
1314  reference r1 = cell_any_reference(c1);
1315  reference r2 = cell_any_reference(c2);
1316  entity v1 = reference_variable(r1);
1317  entity v2 = reference_variable(r2);
1318  return v1==v2;
1319 }

References cell_any_reference(), and reference_variable.

Referenced by points_to_sink_to_sources().

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

◆ cell_included_p()

bool cell_included_p ( cell  c1,
cell  c2 
)

Check that all memory locations denoted by cell "c1" are included in cell "c2".

Has to be extended for GAPs

Parameters
c11
c22

Definition at line 1294 of file effects.c.

1295 {
1296  /* Has to be extended for GAPs */
1297  reference r1 = cell_any_reference(c1);
1298  reference r2 = cell_any_reference(c2);
1299  return points_to_reference_included_p(r1, r2);
1300 }
bool points_to_reference_included_p(reference r1, reference r2)
FI->FC/AM: some elements of the lattice must be exploited here...
Definition: effects.c:1243

References cell_any_reference(), and points_to_reference_included_p().

Referenced by generic_points_to_source_to_sinks(), points_to_sink_to_sources(), and source_subset_in_set_p().

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

◆ cell_indices()

list cell_indices ( cell  c)

Definition at line 64 of file effects.c.

65 {
66  list l_res = NIL;
67  if (cell_gap_p(c))
68  pips_internal_error("GAPs not implemented yet\n");
69  else
71  return l_res;
72 }

References cell_any_reference(), cell_gap_p, NIL, pips_internal_error, and reference_indices.

Referenced by c_convex_effects_on_actual_parameter_forward_translation(), generic_effect_find_aliases_with_simple_pointer_values(), simple_cells_inclusion_p(), and simple_cells_intersection_p().

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

◆ cell_must_point_to_nowhere_sink_in_set_p()

bool cell_must_point_to_nowhere_sink_in_set_p ( cell  source,
set  pts 
)

How are array handled in pts? do we have arcs "a->a"?

Parameters
sourceource
ptsts

Definition at line 870 of file points_to.c.

871 {
872  bool nowhere_p = false;
874  pips_assert("The cell is a pointer", !array_type_p(st) && pointer_type_p(st));
875  //type st = points_to_cell_to_concrete_type(source);
876  //if(!array_type_p(st) && pointer_type_p(st)) {
877  SET_FOREACH(points_to, pt, pts) {
878  cell pt_source = points_to_source(pt);
879  if(cell_equal_p(pt_source, source)) {
880  //if(cell_equivalent_p(pt_source, source)) {
881  cell pt_sink = points_to_sink(pt);
882  if(null_cell_p(pt_sink))
883  ;
884  else if(nowhere_cell_p(pt_sink)) {
886  nowhere_p = approximation_must_p(ap) || approximation_exact_p(ap);
887  break;
888  }
889  else {
890  ;
891  }
892  }
893  }
894  //}
895  return nowhere_p;
896 }
bool cell_equal_p(cell, cell)
CELLS.
Definition: effects.c:1226
type points_to_cell_to_concrete_type(cell)
Definition: type.c:676
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
#define points_to_approximation(x)
#define points_to_sink(x)
#define points_to_source(x)
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993

References approximation_exact_p, approximation_must_p, array_type_p(), cell_equal_p(), nowhere_cell_p(), null_cell_p(), pips_assert, pointer_type_p(), points_to_approximation, points_to_cell_to_concrete_type(), points_to_sink, points_to_source, and SET_FOREACH.

Referenced by recursive_filter_formal_context_according_to_actual_context().

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

◆ cell_points_to_non_null_sink_in_set_p()

bool cell_points_to_non_null_sink_in_set_p ( cell  source,
set  pts 
)

A set of functions called cell_points_to_xxxx(cell s, set pts) where set pts is a points-to relation set.

The definition domain of these functions is key to their use:

  1. if the type of the source s is not a pointer type, should we return false or abort because s is not in the definition domain?
  2. if source s does not appear at all in pts, should we return false or abort because s is not in the definition domain?

If both conditions are selected, the resulting definition domain is the definition domain of the mapping pts.

If a more relaxed definition domain is sometimes useful, then strict and non-strict versions of these functions should be provided, with a clear semantics for their true and false results.

Because cell s may point to one or many cells in pts, which is a relation and not a mapping, the caller may be interested in a may or must point. The information may be convened directly by using distinct function names, cell_must_points_to_xxxx or cell_may_points_to_xxxx, or by adding a pointer to a boolean, exact_p, in the function profiles, which may save time by not looping twice on pts arcs.

This can be implemented using the approximation information of the arcs in pts... if it is trusted. Or recomputed from the arcs in pts.

Flexibility is also introduced by the use of cell_equivalent_p() instead of cell_equal_p(). If the former is used, cells derived from cell s are considered when s if not a pointer. This leads to weird behaviors. For instance, if the source s is a struct, s.f1 and s.f2 will be considered. If s.f1 points to some concrete location and s.f2 points to nowhere (undefined pointer), what result should be returned? The advantage is that the caller does not have to generate s.f1 and s.f2 which are simply found in set pts. Does cell "source" points toward a non null fully defined cell in points-to set pts?

The function name is not well chosen. Something like cell_points_to_defined_cell_p()/

Parameters
sourceource
ptsts

Definition at line 822 of file points_to.c.

823 {
824  bool non_null_p = false;
826  pips_assert("The cell is a pointer", !array_type_p(st) && pointer_type_p(st));
827  SET_FOREACH(points_to, pt, pts) {
828  cell pt_source = points_to_source(pt);
829  if(cell_equal_p(pt_source, source)) {
830  //if(cell_equivalent_p(pt_source, source)) {
831  cell pt_sink = points_to_sink(pt);
832  if(null_cell_p(pt_sink))
833  ;
834  else if(nowhere_cell_p(pt_sink))
835  ;
836  else {
837  non_null_p = true;
838  break;
839  }
840  }
841  }
842  return non_null_p;
843 }

References array_type_p(), cell_equal_p(), nowhere_cell_p(), null_cell_p(), pips_assert, pointer_type_p(), points_to_cell_to_concrete_type(), points_to_sink, points_to_source, and SET_FOREACH.

Referenced by filter_formal_context_according_to_actual_context(), new_filter_formal_context_according_to_actual_context(), and recursive_filter_formal_context_according_to_actual_context().

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

◆ cell_points_to_nowhere_sink_in_set_p()

bool cell_points_to_nowhere_sink_in_set_p ( cell  source,
set  pts 
)
Parameters
sourceource
ptsts

Definition at line 845 of file points_to.c.

846 {
847  bool nowhere_p = false;
849  pips_assert("The cell is a pointer", !array_type_p(st) && pointer_type_p(st));
850  SET_FOREACH(points_to, pt, pts) {
851  cell pt_source = points_to_source(pt);
852  if(cell_equal_p(pt_source, source)) {
853  //if(cell_equivalent_p(pt_source, source)) {
854  cell pt_sink = points_to_sink(pt);
855  if(null_cell_p(pt_sink))
856  ;
857  else if(nowhere_cell_p(pt_sink)) {
858  nowhere_p = true;
859  break;
860  }
861  else {
862  ;
863  }
864  }
865  }
866  return nowhere_p;
867 }

References array_type_p(), cell_equal_p(), nowhere_cell_p(), null_cell_p(), pips_assert, pointer_type_p(), points_to_cell_to_concrete_type(), points_to_sink, points_to_source, and SET_FOREACH.

Referenced by recursive_filter_formal_context_according_to_actual_context().

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

◆ cell_points_to_null_sink_in_set_p()

bool cell_points_to_null_sink_in_set_p ( cell  source,
set  pts 
)
Parameters
sourceource
ptsts

Definition at line 898 of file points_to.c.

899 {
900  bool null_p = false;
902  pips_assert("The cell is a pointer", !array_type_p(st) && pointer_type_p(st));
903  SET_FOREACH(points_to, pt, pts) {
904  cell pt_source = points_to_source(pt);
905  if(cell_equal_p(pt_source, source)) {
906  cell pt_sink = points_to_sink(pt);
907  if(null_cell_p(pt_sink)) {
908  null_p = true;
909  break;
910  }
911  }
912  }
913  return null_p;
914 }

References array_type_p(), cell_equal_p(), null_cell_p(), pips_assert, pointer_type_p(), points_to_cell_to_concrete_type(), points_to_sink, points_to_source, and SET_FOREACH.

Referenced by recursive_filter_formal_context_according_to_actual_context().

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

◆ cell_reference_compare()

int cell_reference_compare ( reference pr1,
reference pr2 
)

compare.c

result

same entity, sort on indices values

not same entity, sort on entity name

sort on module name

if same module name: sort on entity local name

else: current module and top_level come first, then others in lexicographic order

Parameters
pr1r1
pr2r2

Definition at line 54 of file compare.c.

55 {
56  int c1_pos = 0; /* result */
57  reference r1 = *pr1;
58  reference r2 = *pr2;
59  entity e1 = reference_variable(r1);
60  entity e2 = reference_variable(r2);
61 
62  if(same_entity_p(e1, e2))
63  {
64  /* same entity, sort on indices values */
65  list dims1 = reference_indices(r1);
66  list dims2 = reference_indices(r2);
67 
68  size_t nb_dims1 = gen_length(dims1);
69  size_t nb_dims2 = gen_length(dims2);
70 
71  for(;!ENDP(dims1) && !ENDP(dims2) && c1_pos == 0; POP(dims1), POP(dims2))
72  {
73  expression e1 = EXPRESSION(CAR(dims1));
74  expression e2 = EXPRESSION(CAR(dims2));
75 
78  c1_pos = 0;
79  else
80  c1_pos = 1;
81  else
83  c1_pos = -1;
84  else
85  {
87  syntax s2 = expression_syntax(e2);
89  {
92 
93  if (!same_entity_p(e1, e2))
94  c1_pos = strcmp(entity_name(e1),entity_name(e2));
95  }
96  else
97  {
98  intptr_t i1 = 0;
99  intptr_t i2 = 0;
100  intptr_t diff = 0;
101 
102  int r1 = expression_integer_value(e1, &i1);
103  int r2 = expression_integer_value(e2, &i2);
104 
105  if (r1 && r2)
106  {
107  diff = i1 - i2;
108  c1_pos = diff==0? 0 : (diff>0?1:-1);
109  }
110  else
111  {
112  string ch1 = expression_to_string(e1);
113  string ch2 = expression_to_string(e2);
114  c1_pos = strcmp(ch1, ch2);
115  free(ch1);
116  free(ch2);
117  }
118  }
119  }
120  }
121 
122  if (c1_pos == 0)
123  c1_pos = (nb_dims1 < nb_dims2) ? -1 : ( (nb_dims1 > nb_dims2) ? 1 : 0);
124  }
125  else
126  {
127  /* not same entity, sort on entity name */
128  /* sort on module name */
129  char * mod1 = strdup(entity_module_name(e1));
130  string mod2 = strdup(entity_module_name(e2));
131 
132  c1_pos = strcmp(mod1, mod2);
133  /* if same module name: sort on entity local name */
134  if (c1_pos == 0)
135  {
136  c1_pos = strcmp(entity_user_name(e1), entity_user_name(e2));
137  }
138  /* else: current module and top_level come first, then others in lexicographic order */
139  else
140  {
142  const char* current_mod = module_local_name(module);
143  if (strcmp(current_mod, mod1) == 0)
144  {
145  if (top_level_entity_p(e2))
146  c1_pos = strcmp(entity_user_name(e1), entity_user_name(e2));
147  else
148  c1_pos = -1;
149  }
150  else if (strcmp(current_mod, mod2) == 0)
151  {
152  if (top_level_entity_p(e1))
153  c1_pos = strcmp(entity_user_name(e1), entity_user_name(e2));
154  else
155  c1_pos = 1;
156  }
157  else if (top_level_entity_p(e1))
158  c1_pos = -1;
159  else if (top_level_entity_p(e2))
160  c1_pos = 1;
161  }
162  free(mod1); free(mod2);
163  }
164 
165  return c1_pos;
166 }
static entity current_mod
Definition: alias_check.c:120
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
static char * module
Definition: pips.c:74
string expression_to_string(expression e)
Definition: expression.c:77
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
#define syntax_reference_p(x)
Definition: ri.h:2728
#define syntax_reference(x)
Definition: ri.h:2730
#define expression_syntax(x)
Definition: ri.h:1247
s1
Definition: set.c:247
#define intptr_t
Definition: stdint.in.h:294

References CAR, current_mod, ENDP, entity_module_name(), entity_name, entity_user_name(), EXPRESSION, expression_integer_value(), expression_syntax, expression_to_string(), free(), gen_length(), get_current_module_entity(), intptr_t, module, module_local_name(), POP, reference_indices, reference_variable, s1, same_entity_p(), strdup(), syntax_reference, syntax_reference_p, top_level_entity_p(), and unbounded_expression_p().

Referenced by cell_compare(), and compare_effect_reference().

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

◆ cell_reference_to_type()

type cell_reference_to_type ( reference  ref,
bool to_be_freed 
)

computes the type of a cell reference representing a memory access path.

Cell references are not compatible with entity typing: spurious dimensions are added to handle struct fields and the dereferencing operator. BEWARE : does not work if field entity indices have been converted to ranks.

Parameters
refis a reference from a cell.
Returns
a newly allocated type corresponding to the type of the memory cells targeted by the access path.

in particular, gets rid of non-store effect references

A reference to a function returns a pointer to a function of the very same time

FI: for some abstract locations that have type unknown instead of type variable, with basic overloaded

Parameters
refef
to_be_freedo_be_freed

Definition at line 466 of file type.c.

467 {
468  debug_on("EFFECTS-UTIL_DEBUG_LEVEL");
469  type t = type_undefined;
471  *to_be_freed= false;
472 
473  pips_debug(6, "input reference: %s \n", reference_to_string(ref));
474 
475  if (ENDP(reference_indices(ref))) /* in particular, gets rid of non-store effect references */
476  {
477  t = ref_type;
478  }
479  else
480  {
481  if(type_variable_p(ref_type))
482  {
483  t = r_cell_reference_to_type(reference_indices(ref), ref_type, to_be_freed);
484  }
485  else if(type_functional_p(ref_type))
486  {
487  /* A reference to a function returns a pointer to a function
488  of the very same time */
492  NIL, NIL));
493  *to_be_freed = true;
494  }
495  else if(type_unknown_p(ref_type)) {
496  /* FI: for some abstract locations that have type unknown
497  instead of type variable, with basic overloaded */
498  t = ref_type;
499  *to_be_freed = false;
500  }
501  else
502  {
503  pips_internal_error("Bad reference type tag %d \"%s\" for reference %s",
504  type_tag(ref_type),
505  type_to_string(ref_type),
507  }
508  }
509  debug_off();
510  return t;
511 }
basic make_basic(enum basic_utype tag, void *val)
Definition: ri.c:155
type copy_type(type p)
TYPE.
Definition: ri.c:2655
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
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
static type r_cell_reference_to_type(list ref_l_ind, type current_type, bool *to_be_freed)
Lines 291 to 682.
Definition: type.c:315
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160
#define type_functional_p(x)
Definition: ri.h:2950
@ is_basic_pointer
Definition: ri.h:578
#define type_unknown_p(x)
Definition: ri.h:2956
#define type_undefined
Definition: ri.h:2883

References copy_type(), debug_off, debug_on, ENDP, entity_basic_concrete_type(), entity_name, is_basic_pointer, is_type_variable, make_basic(), make_type(), make_variable(), NIL, pips_debug, pips_internal_error, r_cell_reference_to_type(), ref, reference_indices, reference_to_string(), reference_variable, type_functional_p, type_tag, type_to_string(), type_undefined, type_unknown_p, and type_variable_p.

Referenced by cell_to_type(), formal_points_to_parameter(), multiple_pointer_assignment_to_post_pv(), points_to_reference_to_type(), and references_may_conflict_p().

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

◆ cell_relations_generic_binary_op()

list cell_relations_generic_binary_op ( list  l1,
list  l2,
bool(*)(cell_relation, cell_relation cr1_cr2_combinable_p,
list(*)(cell_relation, cell_relation cr1_cr2_binary_op,
list(*)(cell_relation cr1_unary_op,
list(*)(cell_relation cr2_unary_op,
list(*)(list, list union_op 
)

cell_relations.c

cell_relations.c

beware : modifies l1, l2 and their effects

Parameters
l1and l2 are two lists of cell_relations.
cr1_cr2_combinable_pis a bool function that takes two individual cell_relations as arguments and renders true when they are considered as combinable ;
cr1_cr2_binary_opis a binary operator that combines two individual cell_relations;
cr1_unary_opis a unary operators that deal with the remnants of l1, that is those cell_relations that are not combinable with any effect of l2;
cr2_unary_opis a unary operators that deal with the remnants of l2, that is those cell_relations that are not combinable with any effect of l1;
Returns
a list of cell_relations, combination of l1 and l2.

we first deal with the elements of l1 : those that are combinable with the elements of l2, and the others, which we call the remnants of l1

gen_remove(&l2, EFFECT(CAR(l_cr2)));

cr1 belongs to the remnants of l1 : it is combinable with no effects of l2

we must then deal with the remnants of l2

no memory leaks: l1 and l2 won't be used anymore

Parameters
l11
l22

Definition at line 59 of file cell_relations.c.

67 {
68  list l_res = NIL;
69  list l_cr1 = list_undefined;
70  list l_cr2 = list_undefined;
71 
72  debug_on("CELL_RELATIONS_OPERATORS_DEBUG_LEVEL");
73 
74  pips_debug_pvs(1, "l1:\n", l1);
75  pips_debug_pvs(1, "l2:\n", l2);
76 
77  /* we first deal with the elements of l1 : those that are combinable with
78  * the elements of l2, and the others, which we call the remnants of l1 */
79  for(l_cr1 = l1; !ENDP(l_cr1); POP(l_cr1))
80  {
81  cell_relation cr1 = CELL_RELATION(CAR(l_cr1));
82  list prec_l_cr2 = NIL;
83  bool combinable = false;
84 
85  pips_debug_pv(2, "dealing with cr1:\n", cr1);
86 
87  l_cr2 = l2;
88  while(!ENDP(l_cr2))
89  {
90  cell_relation cr2 = CELL_RELATION(CAR(l_cr2));
91 
92  pips_debug_pv(2, "considering cr2:\n", cr2);
93 
94  if ( (*cr1_cr2_combinable_p)(cr1,cr2) )
95  {
96  pips_debug(2, "combinable\n");
97  combinable = true;
98  list l_res_tmp = (*cr1_cr2_binary_op)(cr1,cr2);
99  l_res = (*union_op)(l_res, l_res_tmp);
100 
101  /* gen_remove(&l2, EFFECT(CAR(l_cr2))); */
102  if (prec_l_cr2 != NIL)
103  CDR(prec_l_cr2) = CDR(l_cr2);
104  else
105  l2 = CDR(l_cr2);
106 
107  free(l_cr2); l_cr2 = NIL;
108  /* */
109  //free_cell_relation(cr1); cr1=cell_relation_undefined;
111  }
112  else
113  {
114  pips_debug(2, "not combinable\n");
115  prec_l_cr2 = l_cr2;
116  l_cr2 = CDR(l_cr2);
117  }
118  }
119 
120  pips_debug_pvs(2, "intermediate l_res 1:\n", l_res);
121 
122  if(!combinable)
123  {
124  /* cr1 belongs to the remnants of l1 : it is combinable
125  * with no effects of l2 */
126  if ( (*cr1_cr2_combinable_p)(cr1,cell_relation_undefined) )
127  l_res = gen_nconc(l_res, (*cr1_unary_op)(cr1));
128  }
129  else
130  {
132  }
133  }
134 
135  pips_debug_pvs(2, "intermediate l_res 2:\n", l_res);
136 
137  /* we must then deal with the remnants of l2 */
138  for(l_cr2 = l2; !ENDP(l_cr2); POP(l_cr2))
139  {
140  cell_relation cr2 = CELL_RELATION(CAR(l_cr2));
141 
142  if ( (*cr1_cr2_combinable_p)(cell_relation_undefined,cr2) )
143  l_res = gen_nconc(l_res, (*cr2_unary_op)(cr2));
144  }
145 
146  pips_debug_pvs(1, "final pvs:\n", l_res);
147 
148  /* no memory leaks: l1 and l2 won't be used anymore */
149  gen_free_list(l1);
150  gen_free_list(l2);
151 
152  debug_off();
153 
154  return l_res;
155 }
void free_cell_relation(cell_relation p)
Definition: effects.c:308
#define pips_debug_pv(level, message, pv)
#define pips_debug_pvs(level, message, l_pv)
#define CELL_RELATION(x)
CELL_RELATION.
Definition: effects.h:479
#define cell_relation_undefined
Definition: effects.h:485
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69

References CAR, CDR, CELL_RELATION, cell_relation_undefined, debug_off, debug_on, ENDP, free(), free_cell_relation(), gen_free_list(), gen_nconc(), list_undefined, NIL, pips_debug, pips_debug_pv, pips_debug_pvs, and POP.

Referenced by simple_pvs_may_union(), and simple_pvs_must_union().

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

◆ cell_to_pointer_cells()

list cell_to_pointer_cells ( cell  c)

If the reference in "c" is not a pointer, see if it can be transformed into a pointer reference by adding subscripts, field subscripts or a combination of both...

The "children" list is built with new cells. No sharing is created between "c" and "children".

Definition at line 1739 of file effects.c.

1740 {
1741  list children = NIL;
1742  pips_assert("Cell \"c\" has no subscripts.",
1744 
1745  children = recursive_cell_to_pointer_cells(c);
1746 
1747  pips_assert("Cell \"c\" has children, "
1748  "or this function would not have been called.", !ENDP(children));
1749  return children;
1750 }
list recursive_cell_to_pointer_cells(cell c)
Definition: effects.c:1680

References cell_any_reference(), ENDP, NIL, pips_assert, recursive_cell_to_pointer_cells(), and reference_indices.

+ Here is the call graph for this function:

◆ cell_to_reference()

reference cell_to_reference ( cell  c)

FI: probably to be moved elsewhere in ri-util.

Here, we only know how to cope (for the time being) with cell_reference and cell_preference, not with cell_gap and other future fields. A bit safer than macro cell_any_reference().

Definition at line 1326 of file effects.c.

1326  {
1328 
1329  if (cell_reference_p(c))
1330  r = cell_reference(c);
1331  else if (cell_preference_p(c))
1333  else
1334  pips_internal_error("GAPs not implemented yet or unexpected cell tag.\n");
1335 
1336  return r;
1337 }
#define cell_preference_p(x)
Definition: effects.h:470

References cell_preference, cell_preference_p, cell_reference, cell_reference_p, pips_internal_error, preference_reference, and reference_undefined.

Referenced by cell_entity_equal_p(), cell_equal_p(), cell_out_of_scope_p(), compute_points_to_kill_set(), first_cell_certainly_includes_second_cell_p(), formal_points_to_parameter(), generic_eval_cell_with_points_to(), generic_reference_to_points_to_matching_list(), generic_transform_sink_cells_from_matching_list(), location_entity(), points_to_cell_name(), points_to_cell_translation(), points_to_compare_cell(), points_to_compare_cells(), points_to_compare_location(), points_to_compare_ptr_cell(), points_to_name(), points_to_rank(), points_to_set_block_projection(), points_to_source_projection(), print_or_dump_points_to(), and word_points_to().

+ Here is the caller graph for this function:

◆ cell_to_type()

type cell_to_type ( cell  c,
bool to_be_freed 
)
Parameters
to_be_freedo_be_freed

Definition at line 513 of file type.c.

514 {
515  pips_assert("a cell cannot be a gap yet\n", !cell_gap_p(c));
517 
518  return cell_reference_to_type(ref, to_be_freed);
519 }
type cell_reference_to_type(reference ref, bool *to_be_freed)
computes the type of a cell reference representing a memory access path.
Definition: type.c:466

References cell_gap_p, cell_preference, cell_reference, cell_reference_p, cell_reference_to_type(), pips_assert, preference_reference, and ref.

Referenced by cell_to_nowhere_sink(), external_call_to_post_pv(), generic_stub_source_to_sinks(), k_limit_points_to(), module_initial_parameter_pv(), safe_intrinsic_to_post_pv(), struct_assignment_to_points_to(), type_compatible_super_cell(), and type_compatible_with_points_to_cell_p().

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

◆ cell_typed_anywhere_locations_p()

bool cell_typed_anywhere_locations_p ( cell  c)

test if a cell is the bottom of the lattice

Definition at line 133 of file anywhere_abstract_locations.c.

134 {
136  bool anywhere_p = reference_typed_anywhere_locations_p(r);
137  return anywhere_p;
138 }
bool reference_typed_anywhere_locations_p(reference r)
test if a reference is the bottom of the lattice

References cell_any_reference(), and reference_typed_anywhere_locations_p().

Referenced by binary_intrinsic_call_to_points_to_sinks(), check_type_of_points_to_cells(), compute_points_to_binded_set(), compute_points_to_gen_set(), dereferencing_subscript_to_points_to(), freeable_points_to_cells(), freed_pointer_to_points_to(), null_equal_condition_to_points_to(), offset_cells(), offset_points_to_cell(), points_to_with_stripped_sink(), print_or_dump_points_to(), source_to_sinks(), and unique_location_cell_p().

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

◆ cells_may_not_point_to_null_p()

bool cells_may_not_point_to_null_p ( list  cl)
Parameters
cll

Definition at line 763 of file points_to.c.

764 {
765  bool may_not_p = true;
766  pips_assert("The input list is not empty", !ENDP(cl));
767  FOREACH(CELL, c, cl) {
768  if(null_cell_p(c) || nowhere_cell_p(c)) {
769  may_not_p = false;
770  break;
771  }
772  }
773  return may_not_p;
774 }
#define CELL(x)
CELL.
Definition: effects.h:424
#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

References CELL, ENDP, FOREACH, nowhere_cell_p(), null_cell_p(), and pips_assert.

Referenced by intrinsic_call_condition_to_points_to().

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

◆ cells_must_point_to_null_p()

bool cells_must_point_to_null_p ( list  cl)
Parameters
cll

Definition at line 750 of file points_to.c.

751 {
752  bool must_p = true;
753  pips_assert("The input list is not empty", !ENDP(cl));
754  FOREACH(CELL, c, cl) {
755  if(!null_cell_p(c)) {
756  must_p = false;
757  break;
758  }
759  }
760  return must_p;
761 }

References CELL, ENDP, FOREACH, null_cell_p(), and pips_assert.

Referenced by intrinsic_call_condition_to_points_to().

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

◆ check_abstract_locations()

void check_abstract_locations ( void  )

For debugging the API.

top

bottom

null pointer

all locations for a given module

all heap locations for a given module

all stack locations for a given module

all static locations for a given module

all dynamic locations for a given module

all heap locations for an application

all stack locations for an application

all static locations for an application

all dynamic locations for an application

Should/could be extended to check the max computation...

Definition at line 906 of file anywhere_abstract_locations.c.

907  {
909  /* top */
910  al = entity_all_locations();
911  fprintf(stderr, "top: %s is %s\n", entity_name(al),
913  "the set of all application locations" : "bug!!!");
914 
915  /* bottom */
917  fprintf(stderr, "bottom: %s is %s\n", entity_name(al),
919  "the bottom of the abstract location lattice" : "bug!!!");
920 
921  /* null pointer */
922  al = entity_null_locations();
923  fprintf(stderr, "null: %s is %s\n", entity_name(al),
925  "the null pointer" : "bug!!!");
926 
927  /* all locations for a given module */
929  fprintf(stderr, "all module locations: %s is %s\n", entity_name(al),
931  "the set of all locations of a module" : "bug!!!");
932 
933  /* all heap locations for a given module */
935  fprintf(stderr, "all module heap locations: %s is %s\n", entity_name(al),
937  "the set of all heap locations of a module" : "bug!!!");
938 
939  /* all stack locations for a given module */
941  fprintf(stderr, "all module stack locations: %s is %s\n", entity_name(al),
943  "the set of all stack locations of a module" : "bug!!!");
944 
945  /* all static locations for a given module */
947  fprintf(stderr, "all module static locations: %s is %s\n", entity_name(al),
949  "the set of all static locations of a module" : "bug!!!");
950 
951  /* all dynamic locations for a given module */
953  fprintf(stderr, "all module dynamic locations: %s is %s\n", entity_name(al),
955  "the set of all dynamic locations of a module" : "bug!!!");
956 
957 
958  /* all heap locations for an application */
960  fprintf(stderr, "all application heap locations: %s is %s\n", entity_name(al),
962  "the set of all heap locations of an application" : "bug!!!");
963 
964  /* all stack locations for an application */
966  fprintf(stderr, "all application stack locations: %s is %s\n", entity_name(al),
968  "the set of all stack locations of an application" : "bug!!!");
969 
970  /* all static locations for an application */
972  fprintf(stderr, "all application static locations: %s is %s\n", entity_name(al),
974  "the set of all static locations of an applciation" : "bug!!!");
975 
976  /* all dynamic locations for an application */
978  fprintf(stderr, "all module dynamic locations: %s is %s\n", entity_name(al),
980  "the set of all dynamic locations of an application" : "bug!!!");
981 
982  /* Should/could be extended to check the max computation... */
983  }
bool entity_all_module_static_locations_p(entity e)
test if an entity is the a static area
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
entity entity_null_locations()
return TOP-LEVEL:NULL_POINTER The NULL pointer should be a global variable, unique for all modules FI...
entity entity_all_module_dynamic_locations(entity m)
return m:*DYNAMIC**ANYWHERE
entity entity_all_module_heap_locations(entity m)
return m:*HEAP**ANYWHERE
bool entity_all_dynamic_locations_p(entity e)
test if an entity is the set of all dynamic locations
entity entity_all_module_locations(entity m)
return m:ANYWHERE Set of all memory locations related to one module.
entity entity_all_stack_locations()
return ANY_MODULE:STACK
entity entity_all_module_static_locations(entity m)
return m:*DYNAMIC**ANYWHERE
bool entity_all_static_locations_p(entity e)
test if an entity is the set of all static locations
entity entity_all_module_stack_locations(entity m)
return m:*STACK**ANYWHERE
entity entity_all_dynamic_locations()
return ANY_MODULE:DYNAMIC
bool entity_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool entity_all_module_locations_p(entity e)
test if an entity is the set of locations defined in a module
bool entity_all_module_heap_locations_p(entity e)
test if an entity is the a heap area
entity entity_all_heap_locations()
return ANY_MODULE:HEAP
bool entity_all_module_dynamic_locations_p(entity e)
test if an entity is the a dynamic area
entity entity_nowhere_locations()
return ANY_MODULE:NOWHERE
bool entity_all_module_stack_locations_p(entity e)
test if an entity is the a stack area
bool entity_all_stack_locations_p(entity e)
test if an entity is the set of all stack locations
entity entity_all_static_locations()
return ANY_MODULE:STATIC
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References entity_all_dynamic_locations(), entity_all_dynamic_locations_p(), entity_all_heap_locations(), entity_all_heap_locations_p(), entity_all_locations(), entity_all_locations_p(), entity_all_module_dynamic_locations(), entity_all_module_dynamic_locations_p(), entity_all_module_heap_locations(), entity_all_module_heap_locations_p(), entity_all_module_locations(), entity_all_module_locations_p(), entity_all_module_stack_locations(), entity_all_module_stack_locations_p(), entity_all_module_static_locations(), entity_all_module_static_locations_p(), entity_all_stack_locations(), entity_all_stack_locations_p(), entity_all_static_locations(), entity_all_static_locations_p(), entity_name, entity_nowhere_locations(), entity_nowhere_locations_p(), entity_null_locations(), entity_null_locations_p(), entity_undefined, fprintf(), and get_current_module_entity().

+ Here is the call graph for this function:

◆ close_pt_to_list()

void close_pt_to_list ( void  )

◆ compare_effect_reference()

int compare_effect_reference ( effect e1,
effect e2 
)

int compare_effect_reference(e1, e2):

returns -1 if "e1" is before "e2" in the alphabetic order, else +1. "e1" and "e2" are pointers to effect, we compare the names of their reference's entity.

Parameters
e11
e22

Definition at line 210 of file compare.c.

211 {
214  return cell_reference_compare(&r1, &r2);
215 }
#define effect_any_reference(e)
FI: cannot be used as a left hand side.

References cell_reference_compare(), and effect_any_reference.

Referenced by create_step_regions(), and internal_compute_distribution_context().

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

◆ compare_effect_reference_in_common()

int compare_effect_reference_in_common ( effect e1,
effect e2 
)

int compare_effect_reference_in_common(e1, e2):

returns -1 if "e1" is before "e2" in the alphabetic order, else +1. "e1" and "e2" are pointers to effect, we compare the names of their reference's entity with the common name in first if the entity belongs to a common

Parameters
e11
e22

Definition at line 224 of file compare.c.

225 {
226  entity v1, v2;
227  int n1, n2 ,result;
228  string name1, name2;
231  n1 = (v1==(entity)NULL),
232  n2 = (v2==(entity)NULL);
233  name1= strdup((entity_in_common_p(v1)) ?
234  (string) entity_and_common_name(v1):
235  entity_name(v1));
236  name2= strdup((entity_in_common_p(v2)) ?
237  (string) entity_and_common_name(v2):
238  entity_name(v2));
239 
240  result = (n1 || n2)? (n2-n1): strcmp(name1,name2);
241  free(name1);free(name2);
242  return result;
243 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
const char * entity_and_common_name(entity e)
See next function!
Definition: entity.c:654
bool entity_in_common_p(entity e)
Definition: entity.c:1082

References effect_any_reference, entity_and_common_name(), entity_in_common_p(), entity_name, free(), reference_variable, and strdup().

+ Here is the call graph for this function:

◆ compatible_points_to_subscripts_p()

bool compatible_points_to_subscripts_p ( expression  s1,
expression  s2 
)

Two subscript are compatible if they are equal or if one of them is unbounded.

In the ponts-to context s1 and s2 should be either integer constants or field references.

Parameters
s11
s22

Definition at line 1041 of file points_to.c.

1042 {
1043  bool compatible_p = true;
1044  bool u1 = unbounded_expression_p(s1);
1045  if(!u1) {
1046  bool u2 = unbounded_expression_p(s2);
1047  if(!u2) {
1048  /* In the ponts-to context s1 and s2 should be either integer
1049  constants or field references. */
1050  compatible_p = expression_equal_p(s1, s2);
1051  }
1052  }
1053  return compatible_p;
1054 }
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347

References expression_equal_p(), s1, and unbounded_expression_p().

Referenced by points_to_cell_translation().

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

◆ complete_points_to_reference_with_fixed_subscripts()

void complete_points_to_reference_with_fixed_subscripts ( reference  r,
bool  zero_p 
)

Add a set of zero subscripts to a constant memory path reference "r" by side effect.

Used when a partial array reference must be converted into a reference to the first array element (zero_p==true) or to any element (zero_p==false).

The difficulty lies with field subscripts...

Find the current number of effective subscripts: is there a field subscript somewhere?

FI: this may happen when reference "r" is not a constant memory path

Parameters
zero_pero_p

Definition at line 696 of file points_to.c.

697 {
698  type t = type_undefined;
699 
700  // FI: this assert makes sense within the ri-util framework but is
701  // too strong for the kind of references used in effects-util
702  // pips_assert("scalar type", ENDP(reference_indices(r)));
703 
704  /* Find the current number of effective subscripts: is there a field
705  subscript somewhere? */
706  list sl = reference_indices(r);
707  entity v = reference_variable(r);
708  list rsl = gen_nreverse(sl); // sl is no longer available
709  int i = 0;
710  bool field_found_p = false;
711 
712  FOREACH(EXPRESSION, se, rsl) {
713  if(field_expression_p(se)) {
717  field_found_p = true;
718  break;
719  }
720  i++;
721  }
722 
723  if(!field_found_p)
725 
726  variable vt = type_variable(t);
727  list dl = variable_dimensions(vt);
728  int d = (int) gen_length(dl);
729 
730  /* FI: this may happen when reference "r" is not a constant memory path */
731  pips_assert("Not too many subscripts wrt the type.\n", i<=d);
732 
733  list nsl = NIL; // subscript list
734  int j;
735  for(j=i+1;j<=d;j++) {
737  // reference_indices(r) = CONS(EXPRESSION, s, reference_indices(r));
738  nsl = CONS(EXPRESSION, s, nsl);
739  }
740 
743 }
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
expression make_unbounded_expression()
Definition: expression.c:4339
bool field_expression_p(expression e)
The expression is of kind "a", where "a" is a field of some struct "s".
Definition: expression.c:498
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
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832

References CONS, entity_basic_concrete_type(), EXPRESSION, expression_reference(), f(), field_expression_p(), FOREACH, gen_length(), gen_nconc(), gen_nreverse(), int, int_to_expression(), make_unbounded_expression(), NIL, pips_assert, reference_indices, reference_variable, type_undefined, type_variable, and variable_dimensions.

Referenced by complete_points_to_reference_with_zero_subscripts().

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

◆ complete_points_to_reference_with_zero_subscripts()

void complete_points_to_reference_with_zero_subscripts ( reference  r)

Definition at line 745 of file points_to.c.

746 {
748 }
void complete_points_to_reference_with_fixed_subscripts(reference r, bool zero_p)
Add a set of zero subscripts to a constant memory path reference "r" by side effect.
Definition: points_to.c:696

References complete_points_to_reference_with_fixed_subscripts().

Referenced by dereferencing_subscript_to_points_to(), process_casted_sinks(), process_casted_sources(), and subscript_to_points_to_sinks().

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

◆ constant_memory_access_path_to_location_entity()

entity constant_memory_access_path_to_location_entity ( reference  cp)

A constant memory access path may not be considered.

An undefined entity is returned and the caller must handle the issue.

This occurs, for instance, in the semantics analysis when a wider memory effect contain this constant path. E.g. an untyped anwyhere effect.

It also happens when the caller consider a[*] as a constant reference. It is a constant set of references and no entity is returned.

Parameters
cpp

Definition at line 329 of file locations.c.

330 {
331  entity ecp = entity_undefined;
333  if(!reference_undefined_p(ncp)) {
334  string cp_name = constant_memory_access_path_to_location_name(ncp);
335  free_reference(ncp);
336 
337  // find (or do not create) an entity for the constant path
338  // The entity is supposed to have been created earlier explictly
339  ecp = gen_find_entity(cp_name);
340  if (entity_undefined_p(ecp)) {
341  // pips_internal_error("location entity should have been created explictly during an initialization phase\n");
342  ; // Let the caller deals with the problem
343  }
344  free(cp_name);
345  }
346  return ecp;
347 }
entity gen_find_entity(char *s)
Definition: ri.c:2551
void free_reference(reference p)
Definition: ri.c:2050
static string constant_memory_access_path_to_location_name(reference cp)
package location.
Definition: locations.c:237
reference constant_reference_to_normalized_constant_reference(reference cr)
Allocate a new reference with evaluated subscripts.
Definition: eval.c:1068
#define reference_undefined_p(x)
Definition: ri.h:2303
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87

References constant_memory_access_path_to_location_name(), constant_reference_to_normalized_constant_reference(), cp, entity_undefined, entity_undefined_p, free(), free_reference(), gen_find_entity(), and reference_undefined_p.

Referenced by apply_concrete_effect_to_transformer(), assign_rhs_to_cp_to_transformer(), forward_substitute_array_location_in_transformer(), generic_apply_effect_to_transformer(), generic_effects_maymust_read_or_write_scalar_entity_p(), generic_reference_to_transformer(), generic_unary_operation_to_transformer(), lhs_expression_to_transformer(), new_array_element_backward_substitution_in_transformer(), perform_array_element_substitutions_in_transformer(), pointer_unary_operation_to_transformer(), substitute_struct_stub_in_transformer(), substitute_stubs_in_transformer(), substitute_stubs_in_transformer_with_translation_binding(), transformer_apply_field_assignments_or_equalities(), transformer_apply_unknown_field_assignments_or_equalities(), and update_cp_with_rhs_to_transformer().

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

◆ constant_points_to_indices_p()

bool constant_points_to_indices_p ( list  sl)

check that the subscript list il is either empty or made of integers or fields.

Parameters
sll

Definition at line 1272 of file points_to.c.

1273 {
1274  bool constant_p = true;
1275 
1276  FOREACH(EXPRESSION, se, sl) {
1278  syntax s = expression_syntax(se);
1279  if(syntax_reference_p(s)) {
1280  reference r = syntax_reference(s);
1282  if(!entity_field_p(f)) {
1283  constant_p = false;
1284  break;
1285  }
1286  }
1287  else {
1288  constant_p = false;
1289  break;
1290  }
1291  }
1292  }
1293  return constant_p;
1294 }
static bool constant_p(entity e)
This function return a bool indicating if related entity e represents a constant.
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

References constant_p(), entity_field_p(), EXPRESSION, expression_syntax, extended_integer_constant_expression_p(), f(), FOREACH, reference_variable, syntax_reference, and syntax_reference_p.

+ Here is the call graph for this function:

◆ delete_pt_to_list()

points_to_list delete_pt_to_list ( statement  )

◆ effect_abstract_location_p()

bool effect_abstract_location_p ( effect  eff)
Parameters
effff

Definition at line 280 of file effects.c.

281 {
283 }
bool cell_abstract_location_p(cell c)
Definition: effects.c:273

References cell_abstract_location_p(), and effect_cell.

Referenced by effect_may_union(), effect_must_union(), effects_abstract_location_p(), and region_union().

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

◆ effect_action_kind()

action_kind effect_action_kind ( effect  eff)
Parameters
effff

Definition at line 1055 of file effects.c.

1056 {
1057  action ac = effect_action(eff);
1058  return action_to_action_kind(ac);
1059 }
action_kind action_to_action_kind(action a)
Without the consistency test, this function would certainly be inlined.
Definition: effects.c:1048
#define effect_action(x)
Definition: effects.h:642

References action_to_action_kind(), and effect_action.

Referenced by entity_written_p(), functionnal_on_effects(), no_write_effects_on_var(), and some_conflicts_between().

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

◆ effect_comparable_p()

bool effect_comparable_p ( effect  e1,
effect  e2 
)

Can we merge these two effects because they are equal or because they only differ by their approximations and their descriptors?

Check the subscript lists because p and p[0] do not refer the same memory locations at all

Parameters
e11
e22

Definition at line 587 of file effects.c.

588 {
589  bool comparable_p = false;
592  entity v1 = reference_variable(r1);
593  entity v2 = reference_variable(r2);
594 
595  if(v1==v2) {
596  action a1 = effect_action(e1);
597  action a2 = effect_action(e2);
598  if(action_equal_p(a1, a2))
599  {
600 
601  /* Check the subscript lists because p and p[0] do not refer
602  the same memory locations at all */
603  list sl1 = reference_indices(r1);
604  list sl2 = reference_indices(r2);
605  if(gen_length(sl1)==gen_length(sl2))
606  {
607  list csl1 = list_undefined;
608  list csl2 = list_undefined;
609  bool equal_p = true;
610 
611  for(csl1=sl1, csl2=sl2; !ENDP(csl1) && equal_p; POP(csl1), POP(csl2))
612  {
613  expression e1 = EXPRESSION(CAR(csl1));
614  expression e2 = EXPRESSION(CAR(csl2));
615  equal_p = expression_equal_p(e1, e2);
616  }
617  comparable_p = equal_p;
618  }
619 
620  }
621  }
622 
623  return comparable_p;
624 }
bool action_equal_p(action a1, action a2)
Definition: effects.c:1023

References action_equal_p(), CAR, effect_action, effect_any_reference, ENDP, EXPRESSION, expression_equal_p(), gen_length(), list_undefined, POP, reference_indices, and reference_variable.

Referenced by concerned_entity_p(), and step_get_comparable_effects().

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

◆ effect_compare()

int effect_compare ( effect peff1,
effect peff2 
)

Compares two effects for sorting.

The first criterion is based on names. Local entities come first; then they are sorted according to the lexicographic order of the module name, and inside each module name class, according to the local name lexicographic order. Then for a given entity name, a read effect comes before a write effect. It is assumed that there is only one effect of each type per entity. bc.

same paths, sort on action, reads first

Parameters
peff1eff1
peff2eff2

Definition at line 187 of file compare.c.

188 {
189  int eff1_pos = 0;
190 
191  eff1_pos = cell_compare(&effect_cell(*peff1), &effect_cell(*peff2));
192  if (eff1_pos == 0)
193  {
194  /* same paths, sort on action, reads first */
195  if (effect_read_p(*peff1))
196  eff1_pos = -1;
197  else if (effect_read_p(*peff2))
198  eff1_pos = 1;
199  else eff1_pos = 0;
200  }
201  return(eff1_pos);
202 }
int cell_compare(cell *c1, cell *c2)
Definition: compare.c:168
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))

References cell_compare(), effect_cell, and effect_read_p.

+ Here is the call graph for this function:

◆ effect_entity()

◆ effect_field_dimension_entity()

entity effect_field_dimension_entity ( expression  exp,
list  l_fields 
)

type.c

Parameters
expis an effect index expression which is either the rank or an entity corresponding to a struct, union or enum field
l_fieldsis the list of fields of the corresponding struct, union or enum
Returns
the entity corresponding to the field.
Parameters
expxp
l_fields_fields

Definition at line 51 of file type.c.

52 {
54  {
55  int rank = expression_to_int(exp);
56  return ENTITY(gen_nth(rank-1, l_fields));
57  }
58  else
59  {
60  return expression_to_entity(exp);
61  }
62 }
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
static entity rank
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References ENTITY, exp, expression_constant_p(), expression_to_entity(), expression_to_int(), gen_nth(), and rank.

Referenced by effect_indices_first_pointer_dimension_rank().

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

◆ effect_interference()

effect effect_interference ( effect  eff1,
effect  eff2 
)

Modifies effect eff1 to make sure that any memory state modification abstracted by eff2 preserves the correctness of eff1: all memory locations included in eff1 at input are included in the memory locations abstracted by the new eff1 after the abstract state transition.

FI: seems to extend naturally to new kinds of effects...

default value

nothing to worry about

pointer-dependence write, indexed or not

The base address for the write is constant, the indices should be be checked

The write effect is a direct effet, the other effect may be direct or indirect, indexed or not.

FI: should be very similar to reference_with_store_independent_indices()?

Does the write impact some indices of the read?

May be shared because of persistant references

Parameters
eff1ff1
eff2ff2

Definition at line 863 of file effects.c.

864 {
865  //action ac1 = effect_action(eff1);
866  action ac2 = effect_action(eff2);
867  effect n_eff1 = eff1; /* default value */
868 
869  ifdebug(1) {
870  pips_assert("The new effect is consistent", effect_consistent_p(eff1));
871  pips_assert("The new effect is consistent", effect_consistent_p(eff2));
872  }
873 
874  if(store_independent_effect_p(eff1)) {
875  /* nothing to worry about */
876  ;
877  }
878  else if(action_write_p(ac2)) {
879  if(anywhere_effect_p(eff2)) {
880  // free_effect(eff1);
881  n_eff1 = effect_to_store_independent(eff1);
882  }
883  else {
884  reference r2 = effect_any_reference(eff2);
885  entity v2 = reference_variable(r2);
886  type t2 = ultimate_type(entity_type(v2));
887 
888  if(pointer_type_p(t2)) {
889  /* pointer-dependence write, indexed or not */
891  }
892  else {
893  /* The base address for the write is constant, the indices should be be checked */
894  /* The write effect is a direct effet, the other effect may be
895  direct or indirect, indexed or not. */
896  reference r1 = effect_any_reference(eff1);
897  list ind1 = reference_indices(r1);
898  list cind1 = list_undefined;
899 
900  /* FI: should be very similar to reference_with_store_independent_indices()? */
901 
902  /* Does the write impact some indices of the read? */
903  for(cind1 = ind1; !ENDP(ind1); POP(ind1)) {
904  expression s = EXPRESSION(CAR(cind1));
905  list rl = NIL;
906  list crl = list_undefined;
907  bool interfere_p = false;
908 
909  rl = expression_to_reference_list(s, rl);
910  for(crl=rl; !ENDP(rl); POP(rl)) {
911  reference r = REFERENCE(CAR(crl));
912  entity v = reference_variable(r);
913  if(v2==v) {
914  interfere_p = true;
915  break;
916  }
917  }
918 
919  if(interfere_p) {
920  pips_debug(8, "Interference detected\n");
921  /* May be shared because of persistant references */
922  //free_expression(s);
924  }
925  }
926  }
927  }
928  }
929  ifdebug(1)
930  pips_assert("The new effect is consistent", effect_consistent_p(n_eff1));
931  return n_eff1;
932 }
bool anywhere_effect_p(effect e)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
effect effect_to_pointer_store_independent_effect(effect eff, entity p)
Modify eff so that the set of memory locations decribed after a write to some pointer p is still in t...
Definition: effects.c:815
bool store_independent_effect_p(effect eff)
Does this effect define the same set of memory locations regardless of the current (environment and) ...
Definition: effects.c:636
effect effect_to_store_independent(effect eff)
Definition: effects.c:772
bool effect_consistent_p(effect p)
Definition: effects.c:457
list expression_to_reference_list(expression e, list lr)
conversion of an expression into a list of references; references are appended to list lr as they are...
Definition: expression.c:1263
type ultimate_type(type)
Definition: type.c:3466
#define REFERENCE(x)
REFERENCE.
Definition: ri.h:2296
#define EXPRESSION_(x)
Definition: ri.h:1220
return(s1)

References action_write_p, anywhere_effect_p(), CAR, effect_action, effect_any_reference, effect_consistent_p(), effect_to_pointer_store_independent_effect(), effect_to_store_independent(), ENDP, entity_type, EXPRESSION, EXPRESSION_, expression_to_reference_list(), ifdebug, list_undefined, make_unbounded_expression(), NIL, pips_assert, pips_debug, pointer_type_p(), POP, REFERENCE, reference_indices, reference_variable, store_independent_effect_p(), and ultimate_type().

+ Here is the call graph for this function:

◆ effect_list_can_be_safely_full_freed_p()

bool effect_list_can_be_safely_full_freed_p ( list  el)

Check if some references might be freed with the effects.

This may lead to disaster if the references are part of another PIPS data structure. This information is not fully accurate, but conservative.

The free is very likely to be unsafe

Is it a possible C reference or is it a synthetic reference generated by the effect analysis? Hard to decide...

Parameters
ell

Definition at line 1159 of file effects.c.

1160 {
1161  bool safe_p = true;
1162  FOREACH(EFFECT, e, el) {
1163  cell c = effect_cell(e);
1164  if(cell_reference_p(c)) {
1165  reference r = cell_reference(c);
1166  list inds = reference_indices(r);
1167 
1168  if(ENDP(inds)) {
1169  /* The free is very likely to be unsafe */
1170  //entity v = reference_variable(r);
1171  safe_p = false;
1172  //fprintf(stderr, "cell_reference for %s", entity_name(v));
1173  }
1174  else {
1175  /* Is it a possible C reference or is it a synthetic reference
1176  generated by the effect analysis? Hard to decide... */
1177  //entity v = reference_variable(r);
1178  //fprintf(stderr, "cell_reference for %s", entity_name(v));
1179  //print_reference(r);
1180  }
1181  break;
1182  }
1183  }
1184  return safe_p;
1185 }
#define EFFECT(x)
EFFECT.
Definition: effects.h:608

References cell_reference, cell_reference_p, EFFECT, effect_cell, ENDP, FOREACH, and reference_indices.

Referenced by safe_any_expression_to_transformer().

+ Here is the caller graph for this function:

◆ effect_list_consistent_p()

bool effect_list_consistent_p ( list  el)

Debugging.

Parameters
ell

Definition at line 1340 of file effects.c.

1341 {
1342  bool ok_p = true;
1343 
1344  FOREACH(EFFECT, e, el)
1345  ok_p = ok_p && effect_consistent_p(e);
1346 
1347  return ok_p;
1348 }

References EFFECT, effect_consistent_p(), and FOREACH.

+ Here is the call graph for this function:

◆ effect_on_non_local_variable_p()

bool effect_on_non_local_variable_p ( effect  eff)

Test if an effect has a non local effect.

Parameters
[in]effis the effect to analyse
Returns
true if the effect is on a non local effect
Parameters
effff

Definition at line 674 of file effects.c.

674  {
675  return !same_string_p(
678  );
679 }
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
#define same_string_p(s1, s2)

References effect_any_reference, entity_module_name(), get_current_module_name(), reference_variable, and same_string_p.

Referenced by effects_on_non_local_variable_p().

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

◆ effect_reference_contains_pointer_dimension_p()

bool effect_reference_contains_pointer_dimension_p ( reference  ref,
bool exact_p 
)
Parameters
refis an effect reference
exact_pis a pointer to a bool, which is set to true if the result is not an approximation.
Returns
false if no index corresponds to a pointer dimension, false if any index may correspond to a pointer dimension. If this information is exact, *exact_p is set to true.
Parameters
refef
exact_pxact_p

Definition at line 219 of file type.c.

220 {
221  int pointer_rank;
222  pointer_rank = effect_reference_first_pointer_dimension_rank(ref, exact_p);
223  return (pointer_rank >= 0);
224 }
static int effect_reference_first_pointer_dimension_rank(reference ref, bool *exact_p)
walks thru ref indices and ref entity type arborescence in parallel until a pointer dimension is foun...
Definition: type.c:180

References effect_reference_first_pointer_dimension_rank(), and ref.

+ Here is the call graph for this function:

◆ effect_reference_dereferencing_p()

bool effect_reference_dereferencing_p ( reference  ref,
bool exact_p 
)
Parameters
refis an effect reference
exact_pis a pointer to a bool, which is set to true if the result is not an approximation.
Returns
true if the effect reference may dereference a pointer, false otherwise.

FI: ANY_MODULE:ANYWHERE should not be indexed because any indexing can be eliminated as it results in ANY_MODULE:ANYWHERE

FI: ANY_MODULE:ANYWHERE_b0, 1, 2 should not be indexed because any indexing can be eliminated and the reference replaced by a non-indexed reference to ANY_MODULE:ANYWHERE_bi , j, k depending on the type of the reference.

no dereferencement if scalar reference, in particular, gets rid of non store effect references

Parameters
refef
exact_pxact_p

Definition at line 233 of file type.c.

234 {
235  list l_ind = reference_indices(ref);
236  bool result;
237  int p_rank;
239 
240  //if (entity_all_locations_p(reference_variable(ref)))
242  {
243  if(ENDP(l_ind)) {
244  // result = true;
245  result = false;
246  *exact_p = false;
247  }
248  else {
249  if(entity_all_locations_p(e)) {
250  /* FI: *ANY_MODULE*:*ANYWHERE* should not be indexed because
251  * any indexing can be eliminated as it results in
252  * *ANY_MODULE*:*ANYWHERE*
253  */
254  pips_internal_error("Unexpected indexing of an abstract location.\n");
255  }
257  /* FI: *ANY_MODULE*:*ANYWHERE*_b0, 1, 2 should not be
258  * indexed because any indexing can be eliminated and the
259  * reference replaced by a non-indexed reference to
260  * *ANY_MODULE*:*ANYWHERE*_bi , j, k depending on the type
261  * of the reference.
262  */
263  pips_internal_error("Unexpected indexing of an abstract location.\n");
264  }
265  else {
267 
268  if (p_rank == -1)
269  result = false;
270  else
271  result = p_rank < (int) gen_length(l_ind);
272  }
273  }
274  }
275  else
276  {
277  if (ENDP(l_ind)) /* no dereferencement if scalar reference, in particular, gets rid
278  of non store effect references */
279  p_rank = -1;
280  else
282 
283  if (p_rank == -1)
284  result = false;
285  else
286  result = p_rank < (int) gen_length(l_ind);
287  }
288  return result;
289 }
bool entity_typed_anywhere_locations_p(entity e)
Test if an entity is the bottom of the lattice.

References effect_reference_first_pointer_dimension_rank(), ENDP, entity_abstract_location_p(), entity_all_locations_p(), entity_typed_anywhere_locations_p(), gen_length(), int, pips_internal_error, ref, reference_indices, and reference_variable.

Referenced by can_be_constant_path_p(), convex_effect_to_constant_path_effects_with_pointer_values(), convex_effect_to_constant_path_effects_with_points_to(), effect_to_constant_path_effects_with_points_to(), generic_eval_cell_with_points_to(), references_may_conflict_p(), and simple_effect_to_constant_path_effects_with_pointer_values().

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

◆ effect_reference_to_string()

string effect_reference_to_string ( reference  ref)
Parameters
refef

Definition at line 155 of file prettyprint.c.

156 {
158 }
list effect_words_reference(reference obj)
made from words_reference this function can print entity_name instead of entity_local_name,...
Definition: prettyprint.c:68
string words_to_string(cons *lw)
Definition: print.c:211

References effect_words_reference(), ref, and words_to_string().

Referenced by check_type_of_points_to_cells(), generic_eval_cell_with_points_to(), generic_transform_sink_cells_from_matching_list(), list_assignment_to_points_to(), offset_cell(), points_to_cell_to_string(), reference_dereferencing_to_points_to(), reference_to_points_to_sinks(), references_may_conflict_p(), and references_must_conflict_p().

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

◆ effect_scalar_p()

bool effect_scalar_p ( effect  eff)
Parameters
effff

Definition at line 567 of file effects.c.

568 {
569  bool scalar_p = false;
571  list sl = reference_indices(r);
572  if(ENDP(sl)) {
573  entity v = reference_variable(r);
574  type t = entity_type(v); // basic_concrete_type?
575  int d = type_depth(t);
576  if(d==0)
577  scalar_p = true;
578  else {
579  scalar_p = pointer_type_p(t);
580  }
581  }
582  return scalar_p;
583 }
size_t type_depth(type)
Number of steps to access the lowest leave of type t without dereferencing.
Definition: type.c:4880

References effect_any_reference, ENDP, entity_type, pointer_type_p(), reference_indices, reference_variable, and type_depth().

Referenced by atomic_effect_p(), effect_may_union(), effect_must_union(), first_effect_certainly_includes_second_effect_p(), first_exact_scalar_effect_certainly_includes_second_effect_p(), kill_effects(), and proper_to_summary_simple_effect().

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

◆ effect_to_entity()

entity effect_to_entity ( effect  ef)

Returns the entity corresponding to the mutation.

It could be called effect_to_variable(), but effects are sometimes summarized with abstract locations, i.e. sets of locations.

FI unlikely to work with GAPs

Parameters
eff

Definition at line 1413 of file effects.c.

1414 {
1415  /* FI unlikely to work with GAPs */
1417  entity e = reference_variable(r);
1418 
1419  return e;
1420 }

References effect_any_reference, and reference_variable.

Referenced by add_conflicts().

+ Here is the caller graph for this function:

◆ effect_to_non_pointer_store_independent_effect()

effect effect_to_non_pointer_store_independent_effect ( effect  eff)

Modify eff so that the set of memory locations decribed after a write to some non pointer variable is still in the abstract location set of eff.

\n_eff i = ...; \ eff of stmt s: p[j], q[i],.. s;

Parameters
effff

Definition at line 844 of file effects.c.

845 {
847  //entity v = reference_variable(r);
848  //type t = ultimate_type(entity_type(v));
849 
851 
852  return eff;
853 }
reference reference_with_store_independent_indices(reference r)
Return by side effect a reference whose memory locations includes the memory locations of r in case t...
Definition: expression.c:3045

References effect_any_reference, and reference_with_store_independent_indices().

+ Here is the call graph for this function:

◆ effect_to_pointer_store_independent_effect()

effect effect_to_pointer_store_independent_effect ( effect  eff,
entity  p 
)

Modify eff so that the set of memory locations decribed after a write to some pointer p is still in the abstract location set of eff.

\n_eff p = ...; \ eff of stmt s s;

If p is undefined, assumed that any pointer may have been updated.

As a pointer could be used in indexing, the current implementation is not correct/sufficient

p[i][j] cannot be preserved

No problem: direct scalar reference

Parameters
effff

Definition at line 815 of file effects.c.

816 {
818  entity v = reference_variable(r);
819  //type t = ultimate_type(entity_type(v));
820 
821  if(entity_undefined_p(p) || v==p) {
822  if(!ENDP(reference_indices(r))) {
823  /* p[i][j] cannot be preserved */
825  free_effect(eff);
826  eff = n_eff;
827  }
828  else {
829  /* No problem: direct scalar reference */
830  ;
831  }
832  }
833  return eff;
834 }
effect anywhere_effect(action ac)
Anywhere effect: an effect which can be related to any location of any areas.
Definition: effects.c:317
action copy_action(action p)
ACTION.
Definition: effects.c:77
void free_effect(effect p)
Definition: effects.c:451

References anywhere_effect(), copy_action(), effect_action, effect_any_reference, ENDP, entity_undefined_p, free_effect(), reference_indices, and reference_variable.

Referenced by effect_interference().

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

◆ effect_to_store_independent()

effect effect_to_store_independent ( effect  eff)
Parameters
effff

Definition at line 772 of file effects.c.

773 {
775  entity v = reference_variable(r);
777 
778  if(pointer_type_p(t)) {
780  free_effect(eff);
781  eff = n_eff;
782  }
783  else{
784  list ind = reference_indices(r);
785  list cind = list_undefined;
786 
787  for(cind = ind; !ENDP(cind); POP(cind)) {
788  expression e = EXPRESSION(CAR(cind));
789 
790  if(!unbounded_expression_p(e)) {
792  free_expression(e);
794  }
795  }
796  }
797  }
798 
799  return eff;
800 }

References anywhere_effect(), CAR, copy_action(), effect_action, effect_any_reference, ENDP, entity_type, EXPRESSION, EXPRESSION_, extended_integer_constant_expression_p(), free_effect(), free_expression(), list_undefined, make_unbounded_expression(), pointer_type_p(), POP, reference_indices, reference_variable, ultimate_type(), and unbounded_expression_p().

Referenced by effect_interference().

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

◆ effect_words_reference()

list effect_words_reference ( reference  obj)

prettyprint.c

prettyprint.c

of string

Parameters
objbj

Definition at line 68 of file prettyprint.c.

69 {
70  list pc = NIL;
71  string begin_attachment;
72  entity e = reference_variable(obj);
73 
74  if (get_bool_property("PRETTYPRINT_WITH_COMMON_NAMES")
75  && entity_in_common_p(e)) {
77  } else if (get_bool_property("PRETTYPRINT_EFFECT_WITH_FULL_ENTITY_NAME")) {
78  pc = CHAIN_SWORD(pc, entity_name(e));
79  } else {
80  pc = CHAIN_SWORD(pc, entity_minimal_name(e));
81  }
82 
83  begin_attachment = STRING(CAR(pc));
84 
85  if (reference_indices(obj) != NIL)
86  {
87  string before_first_index = string_undefined;
88  string before_index = string_undefined;
89  string after_index = string_undefined;
90  string after_last_index = string_undefined;
91  string before_field = string_undefined;
92  string after_field = string_undefined;
93 
95  {
98  before_first_index = "(";
99  before_index = "";
100  after_index = ",";
101  after_last_index = ")";
102  before_field = "";
103  after_field = "";
104  break;
105  case is_language_c:
106  before_first_index = "[";
107  before_index = "[";
108  after_index = "]";
109  after_last_index = "]";
110  before_field = ".";
111  after_field = "";
112  break;
113  default:
114  pips_internal_error("Language unknown !");
115  break;
116  }
117 
118  bool first = true;
119  for(list pi = reference_indices(obj); !ENDP(pi); POP(pi))
120  {
121  expression ind_exp = EXPRESSION(CAR(pi));
122  syntax s = expression_syntax(ind_exp);
123  if (syntax_reference_p(s) &&
125  {
126  // add a '.' to disambiguate field names from variable names
127  pc = CHAIN_SWORD(pc, before_field);
128  pc = gen_nconc(pc, Words_Expression(ind_exp));
129  pc = CHAIN_SWORD(pc, after_field);
130  }
131  else
132  {
133  if (first)
134  {
135  pc = CHAIN_SWORD(pc,before_first_index);
136  first = false;
137  }
138  else
139  pc = CHAIN_SWORD(pc,before_index);
140 
141  pc = gen_nconc(pc, Words_Expression(ind_exp));
142  if (CDR(pi) != NIL)
143  pc = CHAIN_SWORD(pc,after_index);
144  else
145  pc = CHAIN_SWORD(pc,after_last_index);
146  }
147  }
148  }
149 
150  attach_reference_to_word_list(begin_attachment, STRING(CAR(gen_last(pc))),
151  obj);
152  return(pc);
153 }
void attach_reference_to_word_list(string begin_word, string end_word, reference r)
Attach a module usage (CALL or function call):
#define STRING(x)
Definition: genC.h:87
enum language_utype get_prettyprint_language_tag()
Definition: language.c:67
const char * entity_minimal_name(entity e)
Do preserve scope informations.
Definition: naming.c:214
list Words_Expression(expression obj)
of string
Definition: misc.c:2616
@ is_language_fortran
Definition: ri.h:1566
@ is_language_fortran95
Definition: ri.h:1568
@ is_language_c
Definition: ri.h:1567
#define CHAIN_SWORD(l, s)

References attach_reference_to_word_list(), CAR, CDR, CHAIN_SWORD, ENDP, entity_and_common_name(), entity_field_p(), entity_in_common_p(), entity_minimal_name(), entity_name, EXPRESSION, expression_syntax, gen_last(), gen_nconc(), get_bool_property(), get_prettyprint_language_tag(), is_language_c, is_language_fortran, is_language_fortran95, NIL, pips_internal_error, POP, reference_indices, reference_variable, STRING, string_undefined, syntax_reference, syntax_reference_p, and Words_Expression().

Referenced by conflicts_sort_callback(), effect_reference_first_pointer_dimension_rank(), effect_reference_to_string(), make_filtered_dg_or_dvdg(), prettyprint_dependence_graph(), prettyprint_dot_dependence_graph(), text_pointer_value(), text_points_to_relation(), text_region_no_action(), words_pointer_value(), and words_points_to().

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

◆ effects_abstract_location_p()

bool effects_abstract_location_p ( list  el)

Returns true if at least one effect of effect list el is related to an abstract location.

Parameters
ell

Definition at line 288 of file effects.c.

289 {
290  bool abstract_p = false;
291 
292  FOREACH(EFFECT, e, el) {
294  abstract_p = true;
295  break;
296  }
297  }
298  return abstract_p;
299 }
bool effect_abstract_location_p(effect eff)
Definition: effects.c:280

References EFFECT, effect_abstract_location_p(), and FOREACH.

Referenced by statement_to_transformer().

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

◆ effects_all_read_p()

bool effects_all_read_p ( list  el)

Check that all effects in el are read effects.

Parameters
ell

Definition at line 1141 of file effects.c.

1142 {
1143  bool result = true;
1144  FOREACH(EFFECT, e, el) {
1145  action a = effect_action(e);
1146  //entity ev = effect_entity(e);
1147  if (action_write_p(a)) {
1148  result = false;
1149  break;
1150  }
1151  }
1152  return result;
1153 }

References action_write_p, EFFECT, effect_action, and FOREACH.

Referenced by regenerate_call().

+ Here is the caller graph for this function:

◆ effects_interfere_p()

bool effects_interfere_p ( effect  eff1,
effect  eff2 
)

Two effects interfere if one of them modify the set of locations defined by the other one.

For instance, an index or a pointer may be used by one effect and changed by the other one.

If a subscript expression is changed, the corresponding subscript must be replaced by an unbounded expression.

If a pointer is written, any indirect effect thru this pointer must be changed into a read or write anywhere.

This function is conservative: it is always correct to declare an interference.

FI: I'm not sure what you can do when you know two effects interfere...

dealing with standard effects

start with complex cases

The write effect is a direct effet, the other effect may be direct or indirect, indexed or not.

Does the write impact the indices of the read?

Parameters
eff1ff1
eff2ff2

Definition at line 714 of file effects.c.

715 {
716  action ac1 = effect_action(eff1);
717  action ac2 = effect_action(eff2);
718  bool interfere_p = false;
719 
720  if(action_write_p(ac1)||action_write_p(ac2)) {
721  if(anywhere_effect_p(eff1) && action_write_p(ac1)) {
722  interfere_p = !store_independent_effect_p(eff2);
723  }
724  else if(anywhere_effect_p(eff2) && action_write_p(ac2)) {
725  interfere_p = !store_independent_effect_p(eff1);
726  }
727  else { /* dealing with standard effects */
728 
729  /* start with complex cases */
730  /* The write effect is a direct effet, the other effect may be
731  direct or indirect, indexed or not. */
735 
736  list rind = list_undefined;
737 
738  if(action_write_p(ac1)) {
739  wr = effect_any_reference(eff1);
740  rr = effect_any_reference(eff2);
741  }
742  else {
743  wr = effect_any_reference(eff2);
744  rr = effect_any_reference(eff1);
745  }
746 
747  wv = reference_variable(wr);
748  rind = reference_indices(rr);
749 
750  /* Does the write impact the indices of the read? */
751  MAP(EXPRESSION, s, {
752  list rl = NIL;
753 
754  rl = expression_to_reference_list(s, rl);
755  MAP(REFERENCE, r, {
756  entity v = reference_variable(r);
757  if(wv==v) {
758  interfere_p = true;
759  break;
760  }
761  }, rl);
762  if(interfere_p)
763  break;
764  }, rind);
765 
766  //interfere_p = true;
767  }
768  }
769  return interfere_p;
770 }
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226

References action_write_p, anywhere_effect_p(), effect_action, effect_any_reference, entity_undefined, EXPRESSION, expression_to_reference_list(), list_undefined, MAP, NIL, REFERENCE, reference_indices, reference_undefined, reference_variable, and store_independent_effect_p().

+ Here is the call graph for this function:

◆ effects_on_non_local_variable_p()

bool effects_on_non_local_variable_p ( list  effects)

Test if a list of effects concerns non local variables.

Parameters
[in]effectsis the effect list to scan
Returns
true if there is an effect on a global variable

Definition at line 687 of file effects.c.

687  {
688  FOREACH(EFFECT,eff,effects)
690  //char * seffect = effect_to_string(eff);
691  //pips_user_warning("effect on non local variable: %s\n",seffect);
692  //free(seffect);
693  return true;
694  }
695  return false;
696 }
bool effect_on_non_local_variable_p(effect eff)
Test if an effect has a non local effect.
Definition: effects.c:674

References EFFECT, effect_on_non_local_variable_p(), and FOREACH.

+ Here is the call graph for this function:

◆ effects_read_variable_p()

bool effects_read_variable_p ( list  el,
entity  v 
)
Parameters
ell

Definition at line 1123 of file effects.c.

1124 {
1125  bool result = false;
1126  if(v) {
1127  FOREACH(EFFECT, e, el) {
1128  action a = effect_action(e);
1129  entity ev = effect_entity(e);
1130  if (action_read_p(a) && store_effect_p(e)
1131  && entities_may_conflict_p(ev,v) ) {
1132  result = true;
1133  break;
1134  }
1135  }
1136  }
1137  return result;
1138 }
entity effect_entity(effect e)
Created by B.
Definition: effects.c:52
bool store_effect_p(effect e)
Definition: effects.c:1062
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984

References action_read_p, EFFECT, effect_action, effect_entity(), entities_may_conflict_p(), FOREACH, and store_effect_p().

Referenced by entity_used_somewhere_walker(), graph_to_live_writes(), loop_annotate(), and vertex_to_chains().

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

◆ effects_to_list()

◆ effects_write_p()

bool effects_write_p ( list  el)
Parameters
ell

Definition at line 1108 of file effects.c.

1109 {
1110  bool result = false;
1111 
1112  FOREACH(EFFECT, e, el) {
1113  action a = effect_action(e);
1114  if (action_write_p(a) && store_effect_p(e)) {
1115  result = true;
1116  break;
1117  }
1118  }
1119 
1120  return result;
1121 }

References action_write_p, EFFECT, effect_action, FOREACH, and store_effect_p().

+ Here is the call graph for this function:

◆ effects_write_variable_p()

bool effects_write_variable_p ( list  el,
entity  v 
)
Parameters
ell

Definition at line 1091 of file effects.c.

1092 {
1093  bool result = false;
1094  if(v) {
1095  FOREACH(EFFECT, e, el) {
1096  action a = effect_action(e);
1097  entity ev = effect_entity(e);
1098  if (action_write_p(a) && store_effect_p(e)
1099  && entities_may_conflict_p(ev,v) ) {
1100  result = true;
1101  break;
1102  }
1103  }
1104  }
1105  return result;
1106 }

References action_write_p, EFFECT, effect_action, effect_entity(), entities_may_conflict_p(), FOREACH, and store_effect_p().

Referenced by block_to_complexity(), graph_to_live_writes(), prune_non_constant(), and vertex_to_chains().

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

◆ effectsmap_to_listmap()

statement_mapping effectsmap_to_listmap ( statement_mapping  efs_map)
Parameters
efs_mapfs_map

Definition at line 228 of file effects.c.

230 {
232 
233  STATEMENT_MAPPING_MAP(s,val,{
234  hash_put((hash_table) l_map, (char *) s, (char *) effects_to_list((effects) val));
235  }, efs_map);
236 
237  return l_map;
238 }
list effects_to_list(effects efs)
Definition: effects.c:209
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
#define MAKE_STATEMENT_MAPPING()
Definition: newgen-local.h:43
#define STATEMENT_MAPPING_MAP(s, v, code, h)
Definition: newgen-local.h:53

References effects_to_list(), hash_put(), MAKE_STATEMENT_MAPPING, and STATEMENT_MAPPING_MAP.

+ Here is the call graph for this function:

◆ entity_abstract_location_p()

bool entity_abstract_location_p ( entity  al)
Parameters
all

Definition at line 641 of file anywhere_abstract_locations.c.

642 {
643 #ifndef NDEBUG
644  const char * en = entity_name(al);
645  const char * module_sep = strchr(en,MODULE_SEP_CHAR);
646  bool abstract_locations_p = ( 0 == strncmp(en,ANY_MODULE_NAME,module_sep++ - en) // << FI: this may change in the future and may not be a strong enough condition
647  || 0 == strncmp(module_sep, ANYWHERE_LOCATION, sizeof(ANYWHERE_LOCATION)-1)
648  || 0 == strncmp(module_sep, STATIC_AREA_LOCAL_NAME, sizeof(STATIC_AREA_LOCAL_NAME)-1)
649  || 0 == strncmp(module_sep, DYNAMIC_AREA_LOCAL_NAME, sizeof(DYNAMIC_AREA_LOCAL_NAME)-1)
650  || 0 == strncmp(module_sep, STACK_AREA_LOCAL_NAME, sizeof(STACK_AREA_LOCAL_NAME)-1)
651  || 0 == strncmp(module_sep, HEAP_AREA_LOCAL_NAME, sizeof(HEAP_AREA_LOCAL_NAME)-1)
652  || 0 == strncmp(module_sep, FORMAL_AREA_LOCAL_NAME, sizeof(HEAP_AREA_LOCAL_NAME)-1)
653  // || 0 == strncmp(module_sep, NULL_POINTER_NAME, sizeof(NULL_POINTER_NAME)-1)
654  )
655  ;
656  pips_assert("entity_kind is consistent",abstract_locations_p == ((entity_kind(al)&ABSTRACT_LOCATION)==ABSTRACT_LOCATION));
657 #endif
658  return (entity_kind(al) & ABSTRACT_LOCATION) ? true : false;
659 }
#define FORMAL_AREA_LOCAL_NAME
Definition: naming-local.h:76
#define DYNAMIC_AREA_LOCAL_NAME
Definition: naming-local.h:69
#define MODULE_SEP_CHAR
Definition: naming-local.h:28
#define STACK_AREA_LOCAL_NAME
Definition: naming-local.h:72
#define STATIC_AREA_LOCAL_NAME
Definition: naming-local.h:70
#define HEAP_AREA_LOCAL_NAME
Definition: naming-local.h:71
#define true
Definition: newgen_types.h:81
@ ABSTRACT_LOCATION
#define entity_kind(x)
Definition: ri.h:2798

References ABSTRACT_LOCATION, ANY_MODULE_NAME, ANYWHERE_LOCATION, DYNAMIC_AREA_LOCAL_NAME, entity_kind, entity_name, FORMAL_AREA_LOCAL_NAME, HEAP_AREA_LOCAL_NAME, MODULE_SEP_CHAR, pips_assert, STACK_AREA_LOCAL_NAME, STATIC_AREA_LOCAL_NAME, and true.

Referenced by add_conflicts(), add_implicit_interprocedural_write_effects(), atomic_constant_path_p(), cell_abstract_location_p(), convex_effect_to_constant_path_effects_with_pointer_values(), create_values_for_simple_effect(), effect_reference_dereferencing_p(), effects_to_dma(), entities_maymust_conflict_p(), entity_locations_max(), generic_apply_effect_to_transformer(), generic_apply_effects_to_transformer(), generic_effects_entities_which_may_conflict_with_scalar_entity(), generic_effects_maymust_read_or_write_scalar_entity_p(), generic_eval_cell_with_points_to(), generic_transform_sink_cells_from_matching_list(), memory_dereferencing_p(), module_to_value_mappings(), opgen_may_name(), opgen_must_name(), opkill_may_name(), opkill_must_name(), points_to_cell_to_upper_bound_points_to_cells(), points_to_compare_cells(), points_to_compare_ptr_cell(), references_may_conflict_p(), simple_effect_to_constant_path_effects_with_pointer_values(), strict_constant_path_p(), struct_assignment_to_points_to(), and variable_to_abstract_location().

+ Here is the caller graph for this function:

◆ entity_all_dynamic_locations()

entity entity_all_dynamic_locations ( void  )

return ANY_MODULE:DYNAMIC

Definition at line 585 of file anywhere_abstract_locations.c.

586 {
588 }
entity entity_all_xxx_locations(string xxx)
return ANY_MODULE:xxx

References DYNAMIC_AREA_LOCAL_NAME, and entity_all_xxx_locations().

Referenced by check_abstract_locations().

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

◆ entity_all_dynamic_locations_p()

bool entity_all_dynamic_locations_p ( entity  e)

test if an entity is the set of all dynamic locations

Definition at line 591 of file anywhere_abstract_locations.c.

592 {
594 }
bool entity_all_xxx_locations_p(entity e, string xxx)
test if an entity is the set of all memory locations in the xxx area of any module.

References DYNAMIC_AREA_LOCAL_NAME, and entity_all_xxx_locations_p().

Referenced by check_abstract_locations(), and strict_constant_path_p().

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

◆ entity_all_heap_locations()

entity entity_all_heap_locations ( void  )

return ANY_MODULE:HEAP

FI->AM: I move it to ANY_MODULE:HEAP**ANYWHERE

Not compatible with entity_all_locations_p()...

Definition at line 494 of file anywhere_abstract_locations.c.

References ANYWHERE_LOCATION, entity_all_xxx_locations(), and HEAP_AREA_LOCAL_NAME.

Referenced by check_abstract_locations(), and malloc_type_to_abstract_location().

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

◆ entity_all_heap_locations_p()

bool entity_all_heap_locations_p ( entity  e)

test if an entity is the set of all heap locations

We look for "*ANY_MODULE*:*HEAP**ANYWHERE*"... unless it is "foo:*HEAP**ANYWHERE*"

FI->AM: this is not compatible with the entity name ANY-MODULE:HEAP

Definition at line 505 of file anywhere_abstract_locations.c.

506 {
508 }

References entity_all_xxx_locations_p(), and HEAP_AREA_LOCAL_NAME.

Referenced by all_heap_locations_cell_p(), check_abstract_locations(), entity_heap_location_p(), heap_intrinsic_to_post_pv(), reference_add_field_dimension(), and strict_constant_path_p().

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

◆ entity_all_heap_locations_typed()

entity entity_all_heap_locations_typed ( type  t)

Definition at line 510 of file anywhere_abstract_locations.c.

511 {
513 }
entity entity_all_xxx_locations_typed(string xxx, type t)
FI->AM: the predicate entity_all_xxx_locations_typed_p() is missing...

References entity_all_xxx_locations_typed(), and HEAP_AREA_LOCAL_NAME.

Referenced by malloc_type_to_abstract_location(), and reference_add_field_dimension().

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

◆ entity_all_locations()

entity entity_all_locations ( void  )

anywhere_abstract_locations.c

anywhere_abstract_locations.c

FI->aM: it was first decided to make this entity an area, but areas cannot be typed. So the internal representation must be changed to carry a type usable according to ALIAS_ACROSS_TYPES. The top of the location lattice should use overloaded as type, that is the top of the type lattice.

Size and layout are unknown

Definition at line 68 of file anywhere_abstract_locations.c.

69 {
70  entity anywhere = entity_undefined;
71  static const char any_name[] =
73  anywhere = gen_find_tabulated(any_name, entity_domain);
74  if(entity_undefined_p(anywhere)) {
75  area a = make_area(0,NIL); /* Size and layout are unknown */
76  type t = make_type_area(a);
77  anywhere = make_entity(strdup(any_name),
78  t,
82  }
83 
84  return anywhere;
85 }
value make_value_unknown(void)
Definition: ri.c:2847
storage make_storage_rom(void)
Definition: ri.c:2285
type make_type_area(area _field_)
Definition: ri.c:2712
area make_area(intptr_t a1, list a2)
Definition: ri.c:98
#define MODULE_SEP_STRING
Definition: naming-local.h:30
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define make_entity(n, t, s, i)
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410

References ABSTRACT_LOCATION, ANY_MODULE_NAME, ANYWHERE_LOCATION, entity_domain, entity_kind, entity_undefined, entity_undefined_p, gen_find_tabulated(), make_area(), make_entity, make_storage_rom(), make_type_area(), make_value_unknown(), MODULE_SEP_STRING, NIL, and strdup().

Referenced by anywhere_effect(), check_abstract_locations(), entity_anywhere_locations(), entity_anywhere_locations_p(), entity_locations_dereference(), generic_entity_typed_anywhere_locations(), make_anywhere_anywhere_pvs(), make_anywhere_points_to_cell(), max_module(), module_initial_parameter_pv(), and points_to_anywhere_sinks().

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

◆ entity_all_locations_p()

bool entity_all_locations_p ( entity  e)

test if an entity is the top of the lattice

This test does not take typed anywhere into account. This is consistent with the function name, but may be not with its uses.

It is not consistent with hiding the impact of ALIASING_ACROSS_TYPES from callers.

Definition at line 100 of file anywhere_abstract_locations.c.

101 {
102 
103  bool anywhere_p;
105  anywhere_p = anywhere_p
107 
108  return anywhere_p;
109 }

References ANY_MODULE_NAME, ANYWHERE_LOCATION, entity_local_name(), entity_module_name(), and same_string_p.

Referenced by anywhere_cell_p(), anywhere_reference_p(), c_convex_effects_on_formal_parameter_backward_translation(), check_abstract_locations(), effect_reference_dereferencing_p(), entities_maymust_conflict_p(), generic_anywhere_effect_p(), interference_on(), loop_variant_list(), opkill_may_name(), opkill_must_name(), pvs_union_combinable_p(), references_may_conflict_p(), simple_pv_may_union(), simple_pv_must_union(), simple_pv_translate(), strict_constant_path_p(), and TestCoupleOfReferences().

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

◆ entity_all_module_dynamic_locations()

entity entity_all_module_dynamic_locations ( entity  m)

return m:*DYNAMIC**ANYWHERE

Definition at line 573 of file anywhere_abstract_locations.c.

574 {
576 }
entity entity_all_module_xxx_locations(entity m, const char *xxx)
return m:xxx*ANYWHERE* Generic set of functions for all kinds of areas

References DYNAMIC_AREA_LOCAL_NAME, and entity_all_module_xxx_locations().

Referenced by check_abstract_locations().

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

◆ entity_all_module_dynamic_locations_p()

bool entity_all_module_dynamic_locations_p ( entity  e)

test if an entity is the a dynamic area

Definition at line 579 of file anywhere_abstract_locations.c.

580 {
582 }
bool entity_all_module_xxx_locations_p(entity e, string xxx)
test if an entity is the set of all memory locations in the xxx area of a module.

References DYNAMIC_AREA_LOCAL_NAME, and entity_all_module_xxx_locations_p().

Referenced by check_abstract_locations(), and strict_constant_path_p().

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

◆ entity_all_module_heap_locations()

entity entity_all_module_heap_locations ( entity  m)

return m:*HEAP**ANYWHERE

Definition at line 471 of file anywhere_abstract_locations.c.

472 {
474 }

References entity_all_module_xxx_locations(), and HEAP_AREA_LOCAL_NAME.

Referenced by check_abstract_locations(), and malloc_type_to_abstract_location().

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

◆ entity_all_module_heap_locations_p()

bool entity_all_module_heap_locations_p ( entity  e)

test if an entity is the a heap area

Definition at line 483 of file anywhere_abstract_locations.c.

References entity_all_module_xxx_locations_p(), and HEAP_AREA_LOCAL_NAME.

Referenced by check_abstract_locations(), entity_heap_location_p(), heap_intrinsic_to_post_pv(), reference_add_field_dimension(), and strict_constant_path_p().

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

◆ entity_all_module_heap_locations_typed()

entity entity_all_module_heap_locations_typed ( entity  m,
type  t 
)

Definition at line 476 of file anywhere_abstract_locations.c.

477 {
480 }
entity entity_all_module_xxx_locations_typed(const char *mn, const char *xxx, type t)

References entity_all_module_xxx_locations_typed(), entity_local_name(), and HEAP_AREA_LOCAL_NAME.

Referenced by malloc_type_to_abstract_location().

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

◆ entity_all_module_locations()

entity entity_all_module_locations ( entity  m)

return m:ANYWHERE Set of all memory locations related to one module.

FI: This may prove useless unless the compilation unit is taken into account.

Size and layout are unknown

FI: any_name?

Definition at line 265 of file anywhere_abstract_locations.c.

266 {
267  entity anywhere = entity_undefined;
268  const char* mn = entity_local_name(m);
269 
270  anywhere = FindEntity(mn,ANYWHERE_LOCATION);
271  if(entity_undefined_p(anywhere)) {
272  area a = make_area(0,NIL); /* Size and layout are unknown */
273  type t = make_type_area(a);
274  /* FI: any_name? */
275  anywhere = CreateEntity(mn,ANYWHERE_LOCATION);
276  entity_type(anywhere)=t;
277  entity_storage(anywhere)=make_storage_rom();
279  entity_kind(anywhere)=ABSTRACT_LOCATION;
280  }
281 
282  return anywhere;
283 }
entity CreateEntity(const char *package_name, const char *local_name)
BEGIN_EOLE.
Definition: entity.c:1572
#define entity_storage(x)
Definition: ri.h:2794

References ABSTRACT_LOCATION, ANYWHERE_LOCATION, CreateEntity(), entity_initial, entity_kind, entity_local_name(), entity_storage, entity_type, entity_undefined, entity_undefined_p, FindEntity(), make_area(), make_storage_rom(), make_type_area(), make_value_unknown(), and NIL.

Referenced by check_abstract_locations().

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

◆ entity_all_module_locations_p()

bool entity_all_module_locations_p ( entity  e)

test if an entity is the set of locations defined in a module

Definition at line 286 of file anywhere_abstract_locations.c.

287 {
288 
289  bool all_module_p;
291 
292  return all_module_p;
293 }

References ANYWHERE_LOCATION, entity_local_name(), and same_string_p.

Referenced by apply_abstract_effect_to_transformer(), check_abstract_locations(), and strict_constant_path_p().

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

◆ entity_all_module_stack_locations()

entity entity_all_module_stack_locations ( entity  m)

return m:*STACK**ANYWHERE

Definition at line 523 of file anywhere_abstract_locations.c.

524 {
526 }

References entity_all_module_xxx_locations(), and STACK_AREA_LOCAL_NAME.

Referenced by check_abstract_locations().

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

◆ entity_all_module_stack_locations_p()

bool entity_all_module_stack_locations_p ( entity  e)

test if an entity is the a stack area

Definition at line 529 of file anywhere_abstract_locations.c.

References entity_all_module_xxx_locations_p(), and STACK_AREA_LOCAL_NAME.

Referenced by check_abstract_locations(), and strict_constant_path_p().

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

◆ entity_all_module_static_locations()

entity entity_all_module_static_locations ( entity  m)

return m:*DYNAMIC**ANYWHERE

Definition at line 548 of file anywhere_abstract_locations.c.

References entity_all_module_xxx_locations(), and STATIC_AREA_LOCAL_NAME.

Referenced by check_abstract_locations().

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

◆ entity_all_module_static_locations_p()

bool entity_all_module_static_locations_p ( entity  e)

test if an entity is the a static area

Definition at line 554 of file anywhere_abstract_locations.c.

References entity_all_module_xxx_locations_p(), and STATIC_AREA_LOCAL_NAME.

Referenced by check_abstract_locations(), and strict_constant_path_p().

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

◆ entity_all_module_xxx_locations()

entity entity_all_module_xxx_locations ( entity  m,
const char *  xxx 
)

return m:xxx*ANYWHERE* Generic set of functions for all kinds of areas

Size and layout are unknown

I: more work to be done here...

Parameters
xxxxx

Definition at line 299 of file anywhere_abstract_locations.c.

300 {
301  entity dynamic = entity_undefined;
302  string any_name;
303  asprintf(&any_name, "%s" ANYWHERE_LOCATION, xxx);
304 
305  //dynamic = gen_find_tabulated(any_name, entity_domain);
306  dynamic = FindOrCreateEntity(entity_local_name(m), any_name);
307  if(storage_undefined_p(entity_storage(dynamic))) {
308  area a = make_area(0,NIL); /* Size and layout are unknown */
309  type t = make_type_area(a);
310  /*FI: more work to be done here... */
311  entity_type(dynamic) = t;
312  entity_storage(dynamic) = make_storage_rom();
313  entity_initial(dynamic) = make_value_unknown();
315  }
316  free(any_name);
317 
318  return dynamic;
319 }
#define asprintf
Definition: misc-local.h:225
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
#define storage_undefined_p(x)
Definition: ri.h:2477

References ABSTRACT_LOCATION, ANYWHERE_LOCATION, asprintf, entity_initial, entity_kind, entity_local_name(), entity_storage, entity_type, entity_undefined, FindOrCreateEntity(), free(), make_area(), make_storage_rom(), make_type_area(), make_value_unknown(), NIL, and storage_undefined_p.

Referenced by entity_all_module_dynamic_locations(), entity_all_module_heap_locations(), entity_all_module_stack_locations(), entity_all_module_static_locations(), and variable_to_abstract_location().

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

◆ entity_all_module_xxx_locations_p()

bool entity_all_module_xxx_locations_p ( entity  e,
string  xxx 
)

test if an entity is the set of all memory locations in the xxx area of a module.

The module is not checked, so it can be the set of all modules...

Parameters
xxxxx

Definition at line 366 of file anywhere_abstract_locations.c.

367 {
368  bool dynamic_p;
369  string s = concatenate(xxx, ANYWHERE_LOCATION, NULL);
370 
371  pips_assert("e is defined", !entity_undefined_p(e));
372 
373  dynamic_p = same_string_p(entity_local_name(e), s);
374 
375  return dynamic_p;
376 }
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183

References ANYWHERE_LOCATION, concatenate(), entity_local_name(), entity_undefined_p, pips_assert, and same_string_p.

Referenced by entity_all_module_dynamic_locations_p(), entity_all_module_heap_locations_p(), entity_all_module_stack_locations_p(), and entity_all_module_static_locations_p().

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

◆ entity_all_module_xxx_locations_typed()

entity entity_all_module_xxx_locations_typed ( const char *  mn,
const char *  xxx,
type  t 
)

A new entity has been created

I: more work to be done here...

no aliasing

Parameters
mnn
xxxxx

Definition at line 321 of file anywhere_abstract_locations.c.

322 {
324  int count = 0;
325  bool found_p = false; // a break could be used instead
326 
327  pips_assert("Type t is defined", !type_undefined_p(t));
328 
329  for(count = 0; !found_p; count++) {
330 
331  type ot = type_undefined;
332  char * local_name;
333 
334  asprintf(&local_name, "%s_b%d", xxx,count);
336  free(local_name);
337  ot = entity_type(e);
338  if(type_undefined_p(ot)) {
339  /* A new entity has been created */
340  //area a = make_area(0,NIL); /* Size and layout are unknown */
341  //type t = make_type_area(a);
342  /*FI: more work to be done here... */
343  entity_type(e) = copy_type(t); /* no aliasing */
346  found_p = true;
347 
348  }
349  else if(type_equal_p(t, ot))
350  found_p = true;
351  }
352 
353  // FI: the debug message should be improved with full information
354  // about the type... See get_symbol_table() and isolate the code
355  // used to prettyprint the type. Too bad it uses the buffer type...
356  pips_debug(8, "New abstract location entity \"%s\" found or created"
357  " with type \"%s\"\n", entity_name(e), type_to_string(t));
358 
359  return e;
360 }
static int count
Definition: SDG.c:519
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
string type_to_string(const type)
type.c
Definition: type.c:51
#define type_undefined_p(x)
Definition: ri.h:2884

References asprintf, copy_type(), count, entity_initial, entity_name, entity_storage, entity_type, entity_undefined, FindOrCreateEntity(), free(), local_name(), make_storage_rom(), make_value_unknown(), pips_assert, pips_debug, type_equal_p(), type_to_string(), type_undefined, and type_undefined_p.

Referenced by entity_all_module_heap_locations_typed(), and variable_to_abstract_location().

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

◆ entity_all_stack_locations()

entity entity_all_stack_locations ( void  )

return ANY_MODULE:STACK

Definition at line 535 of file anywhere_abstract_locations.c.

536 {
538 }

References entity_all_xxx_locations(), and STACK_AREA_LOCAL_NAME.

Referenced by check_abstract_locations().

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

◆ entity_all_stack_locations_p()

bool entity_all_stack_locations_p ( entity  e)

test if an entity is the set of all stack locations

Definition at line 541 of file anywhere_abstract_locations.c.

542 {
544 }

References entity_all_xxx_locations_p(), and STACK_AREA_LOCAL_NAME.

Referenced by check_abstract_locations(), and strict_constant_path_p().

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

◆ entity_all_static_locations()

entity entity_all_static_locations ( void  )

return ANY_MODULE:STATIC

Definition at line 560 of file anywhere_abstract_locations.c.

561 {
563 }

References entity_all_xxx_locations(), and STATIC_AREA_LOCAL_NAME.

Referenced by check_abstract_locations().

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

◆ entity_all_static_locations_p()

bool entity_all_static_locations_p ( entity  e)

test if an entity is the set of all static locations

Definition at line 566 of file anywhere_abstract_locations.c.

567 {
569 }

References entity_all_xxx_locations_p(), and STATIC_AREA_LOCAL_NAME.

Referenced by check_abstract_locations(), and strict_constant_path_p().

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

◆ entity_all_xxx_locations()

entity entity_all_xxx_locations ( string  xxx)

return ANY_MODULE:xxx

I: more work to be done here...

FI: I'd like to make the type variable, overloaded,...

Parameters
xxxxx

Definition at line 379 of file anywhere_abstract_locations.c.

380 {
381  entity dynamic = entity_undefined;
382  dynamic = FindOrCreateEntity(ANY_MODULE_NAME,xxx);
383 
384  if(type_undefined_p(entity_type(dynamic))) {
385  //area a = make_area(0,NIL); /* Size and layout are unknown */
386  //type t = make_type_area(a);
387  /*FI: more work to be done here... */
388  /* FI: I'd like to make the type variable, overloaded,... */
389  // entity_type(dynamic) = make_type_unknown();
391  variable v = make_variable(b, NIL, NIL);
392  entity_type(dynamic) = make_type_variable(v);
393  entity_storage(dynamic) = make_storage_rom();
394  entity_initial(dynamic) = make_value_unknown();
400  }
401 
402  return dynamic;
403 }
type make_type_variable(variable _field_)
Definition: ri.c:2715
basic make_basic_overloaded(void)
Definition: ri.c:167
@ ENTITY_STATIC_AREA
@ ENTITY_DYNAMIC_AREA
@ ENTITY_STACK_AREA
@ ENTITY_HEAP_AREA

References ABSTRACT_LOCATION, ANY_MODULE_NAME, DYNAMIC_AREA_LOCAL_NAME, ENTITY_DYNAMIC_AREA, ENTITY_HEAP_AREA, entity_initial, entity_kind, ENTITY_STACK_AREA, ENTITY_STATIC_AREA, entity_storage, entity_type, entity_undefined, FindOrCreateEntity(), HEAP_AREA_LOCAL_NAME, make_basic_overloaded(), make_storage_rom(), make_type_variable(), make_value_unknown(), make_variable(), NIL, same_string_p, STACK_AREA_LOCAL_NAME, STATIC_AREA_LOCAL_NAME, and type_undefined_p.

Referenced by application_to_points_to_sinks(), entity_all_dynamic_locations(), entity_all_heap_locations(), entity_all_stack_locations(), entity_all_static_locations(), make_anywhere_reference(), make_nowhere_cell(), points_to_anywhere(), and user_call_to_points_to_sinks().

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

◆ entity_all_xxx_locations_p()

bool entity_all_xxx_locations_p ( entity  e,
string  xxx 
)

test if an entity is the set of all memory locations in the xxx area of any module.

FI->AM: how come w generate HEAP and we check HEAP**ANYWHERE?

Parameters
xxxxx

Definition at line 456 of file anywhere_abstract_locations.c.

457 {
458  bool dynamic_p;
459  string s = concatenate(xxx, ANYWHERE_LOCATION, NULL);
460 
461  dynamic_p = same_string_p(entity_local_name(e), s);
462  dynamic_p = dynamic_p
464 
465  return dynamic_p;
466 }

References ANY_MODULE_NAME, ANYWHERE_LOCATION, concatenate(), entity_local_name(), entity_module_name(), and same_string_p.

Referenced by entity_all_dynamic_locations_p(), entity_all_heap_locations_p(), entity_all_stack_locations_p(), and entity_all_static_locations_p().

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

◆ entity_all_xxx_locations_typed()

entity entity_all_xxx_locations_typed ( string  xxx,
type  t 
)

FI->AM: the predicate entity_all_xxx_locations_typed_p() is missing...

A new entity has been created

I: more work to be done here...

Parameters
xxxxx

Definition at line 406 of file anywhere_abstract_locations.c.

407 {
409  int count = 0;
410  bool found_p = false; // a break could be used instead
411 
412  pips_assert("Type t is defined", !type_undefined_p(t));
413  pips_assert("Type t is not functional", !type_functional_p(t));
414 
415  for(count = 0; !found_p; count++) {
416  string name = string_undefined;
417  type ot = type_undefined;
418 
419  asprintf(&name, "%s_b%d", xxx, count);
421  free(name);
422  ot = entity_type(e);
423  if(type_undefined_p(ot)) {
424  /* A new entity has been created */
425  //area a = make_area(0,NIL); /* Size and layout are unknown */
426  //type t = make_type_area(a);
427  /*FI: more work to be done here... */
428  entity_type(e) = copy_type(t);
432  found_p = true;
433  }
434  else if(type_equal_p(t, ot)) // FI: do we want to relax this test?
435  found_p = true;
436  }
437 
438  // FI: the debug message should be improved with full information
439  // about the type... See get_symbol_table() and isolate the code
440  // used to prettyprint the type. Too bad it uses the buffer type...
441  ifdebug(8) {
442  pips_debug(8, "New abstract location entity \"%s\" found or created"
443  " with type ", entity_name(e));
444  print_type(t);
445  fprintf(stderr, "\n");
446  }
447 
448  return e;
449 }
void print_type(type)
For debugging.
Definition: type.c:111

References ABSTRACT_LOCATION, ANY_MODULE_NAME, asprintf, copy_type(), count, entity_initial, entity_kind, entity_name, entity_storage, entity_type, entity_undefined, FindOrCreateEntity(), fprintf(), free(), ifdebug, make_storage_rom(), make_value_unknown(), pips_assert, pips_debug, print_type(), string_undefined, type_equal_p(), type_functional_p, type_undefined, and type_undefined_p.

Referenced by application_to_points_to_sinks(), entity_all_heap_locations_typed(), entity_typed_anywhere_locations(), entity_typed_nowhere_locations(), generic_entity_typed_anywhere_locations(), make_anywhere_points_to_cell(), make_anywhere_reference(), make_typed_nowhere_cell(), points_to_anywhere_typed(), and user_call_to_points_to_sinks().

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

◆ entity_anywhere_locations()

entity entity_anywhere_locations ( void  )

Definition at line 87 of file anywhere_abstract_locations.c.

88 {
89  return entity_all_locations();
90 }

References entity_all_locations().

Referenced by abstract_locations_max(), anywhere_source_to_sinks(), remove_arcs_from_pt_map(), and source_to_sinks().

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

◆ entity_anywhere_locations_p()

bool entity_anywhere_locations_p ( entity  e)

test if an entity is the bottom of the lattice

Definition at line 127 of file anywhere_abstract_locations.c.

128 {
129  return same_entity_p(e, entity_all_locations());
130 }

References entity_all_locations(), and same_entity_p().

Referenced by entities_maymust_conflict_p(), generic_atomic_points_to_reference_p(), module_to_value_mappings(), points_to_cell_translation(), reference_add_field_dimension(), semantics_usable_points_to_reference_p(), and strict_constant_path_p().

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

◆ entity_flow_or_context_sentitive_heap_location()

entity entity_flow_or_context_sentitive_heap_location ( int  stmt_number,
type  t 
)

FI: Beware, the symbol table is updated but this is not reflected in pipsmake.rc

We need to keep track of these pseudo-variables to destroy them before a module is reanalyzed after a code transformation, for instance a constant propagation that changed dependent types into cosntant types.

We might be in trouble, unless a piece of code is reanalyzed. Let's assume the type is unchanged

Parameters
stmt_numbertmt_number

Definition at line 78 of file abstract_location.c.

79 {
80  entity e;
81  string s;
82  asprintf(&s, HEAP_AREA_LOCAL_NAME "_l_%d", stmt_number);
83 
85  free(s);
89  //ram r = make_ram(f, a, UNKNOWN_RAM_OFFSET, NIL);
91 
92  /* FI: Beware, the symbol table is updated but this is not
93  reflected in pipsmake.rc */
95  entity_type(e) = copy_type(ct);
99  (void) add_C_variable_to_area(a, e);
100  /* We need to keep track of these pseudo-variables to destroy them
101  before a module is reanalyzed after a code transformation, for
102  instance a constant propagation that changed dependent types
103  into cosntant types. */
105  }
106  else {
107  /* We might be in trouble, unless a piece of code is
108  reanalyzed. Let's assume the type is unchanged */
110  type et = entity_type(e);
111  // FI: too strong if 1-D arrays and pointers can be assimilated
112  //pips_assert("The type is unchanged",
113  // type_equal_p(ct, et));
114  if(!type_equal_p(ct,et)) {
115  // FI: this might be improvable with array_pointer_type_equal_p
116  if(pointer_type_p(ct) && array_type_p(et)) {
117  type pt = type_to_pointed_type(ct);
119  variable etv = type_variable(et);
120  basic eb = variable_basic(etv);
121  int d = (int) gen_length(variable_dimensions(etv));
122  if(d==1 && basic_equal_p(pb, eb))
123  ;
124  else
125  pips_assert("The type is unchanged or compatible", false);
126  }
127  else if(pointer_type_p(et) && array_type_p(ct)) {
128  type pt = type_to_pointed_type(et);
130  variable etv = type_variable(ct);
131  basic eb = variable_basic(etv);
132  int d = (int) gen_length(variable_dimensions(etv));
133  if(d==1 && basic_equal_p(pb, eb))
134  ;
135  else
136  pips_assert("The type is unchanged or compatible", false);
137  }
138  else
139  pips_assert("The type is unchanged or compatible", false);
140  }
141  free_type(ct);
142  }
143  return e;
144 
145 }
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
Definition: ri.c:1999
storage make_storage_ram(ram _field_)
Definition: ri.c:2279
#define DYNAMIC_RAM_OFFSET
FI: I would have assumed that it is used for the stack area, but I must be wrong.....
entity module_to_heap_area(entity f)
Returns the heap area "a" associated to module "f".
Definition: area.c:129
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
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 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

References ABSTRACT_LOCATION, add_C_variable_to_area(), AddEntityToDeclarations(), array_type_p(), asprintf, basic_equal_p(), compute_basic_concrete_type(), copy_type(), DYNAMIC_RAM_OFFSET, entity_initial, entity_kind, entity_storage, entity_type, f(), FindOrCreateEntity(), free(), free_type(), gen_length(), get_current_module_entity(), get_current_module_name(), HEAP_AREA_LOCAL_NAME, int, make_ram(), make_storage_ram(), make_value_unknown(), module_to_heap_area(), NIL, pips_assert, pointer_type_p(), type_equal_p(), type_to_pointed_type(), type_undefined_p, type_variable, variable_basic, and variable_dimensions.

Referenced by malloc_type_to_abstract_location().

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

◆ entity_flow_or_context_sentitive_heap_location_p()

bool entity_flow_or_context_sentitive_heap_location_p ( entity  e)

Definition at line 147 of file abstract_location.c.

148 {
149  bool result = false;
150  const char* ln = entity_local_name(e);
151  string found = strstr(ln, ANYWHERE_LOCATION);
152 
153  pips_debug(9, "input entity: %s\n", ln);
154  pips_debug(9, "found (1) = : %s\n", found);
155 
156  if (found == NULL)
157  {
158  found = strstr(ln, HEAP_AREA_LOCAL_NAME);
159  pips_debug(9, "found (2) = : %s\n", found);
160  if (found!=NULL)
161  {
162  size_t found_n = strspn(found, HEAP_AREA_LOCAL_NAME);
163  ln = &found[found_n];
164  pips_debug(9, "ln : %s\n", ln);
165  found = strstr(ln, "_l_");
166  pips_debug(9, "found (3) = : %s\n", found);
167  result = (found != NULL);
168  }
169  else
170  result = false;
171  }
172  else
173  result = false;
174  pips_debug(9, "result = %d\n", (int) result);
175  return result;
176 }

References ANYWHERE_LOCATION, entity_local_name(), HEAP_AREA_LOCAL_NAME, and pips_debug.

Referenced by convex_cells_inclusion_p(), convex_cells_intersection_p(), free_to_post_pv(), generic_transform_sink_cells_from_matching_list(), references_may_conflict_p(), simple_cells_inclusion_p(), and simple_cells_intersection_p().

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

◆ entity_heap_location_p()

bool entity_heap_location_p ( entity  b)

abstract_location.c

abstract_location.c

Amira Mensi 2010

File: abstract_location.c

This file contains various useful functions to modelize a heap. check if an entity b may represent a bucket or a set of buckets in the heap.

Definition at line 64 of file abstract_location.c.

65 {
66  bool bucket_p = entity_all_heap_locations_p(b) ||
68 
69  if(!heap_area_p(b) && !bucket_p) {
70  const char* ln = entity_local_name(b);
71  const char* found = strstr(ln, HEAP_AREA_LOCAL_NAME);
72  bucket_p = found != NULL;
73  }
74 
75  return bucket_p;
76 }
bool heap_area_p(entity aire)
Definition: area.c:86

References entity_all_heap_locations_p(), entity_all_module_heap_locations_p(), entity_local_name(), HEAP_AREA_LOCAL_NAME, and heap_area_p().

Referenced by analyzable_scalar_entity_p(), cell_out_of_scope_p(), cells_to_read_or_write_effects(), clean_up_points_to_stubs(), generic_atomic_points_to_reference_p(), generic_eval_cell_with_points_to(), generic_remove_unreachable_vertices_in_points_to_graph(), module_to_value_mappings(), points_to_reference_to_typed_index(), and semantics_usable_points_to_reference_p().

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

◆ entity_locations_dereference()

entity entity_locations_dereference ( entity  )

◆ entity_locations_max()

entity entity_locations_max ( entity  al1,
entity  al2 
)

Here, entity al1 and entity al2 can be program variables.

Both al1 and al2 are abstract locations and they are different

al1 and al2 are assumed to be variables

Parameters
al1l1
al2l2

Definition at line 829 of file anywhere_abstract_locations.c.

830 {
832  //string ln1 = entity_local_name(al1);
833  //string ln2 = entity_local_name(al2);
834 
835  if(al1==al2) {
836  e = al1;
837  }
838  else {
839  bool al1_abstract_location_p = entity_abstract_location_p(al1);
840  bool al2_abstract_location_p = entity_abstract_location_p(al2);
841  if(al1_abstract_location_p )
842  if(al2_abstract_location_p ) {
843  /* Both al1 and al2 are abstract locations and they are
844  different */
845  e = abstract_locations_max(al1, al2);
846  }
847  else {
849  e = abstract_locations_max(al1, al);
850  }
851  else
852  if(al2_abstract_location_p) {
854  e = abstract_locations_max(al, al2);
855  }
856  else {
857  /* al1 and al2 are assumed to be variables */
858  storage s1 = entity_storage(al1);
859  storage s2 = entity_storage(al2);
860 
861  if(storage_ram_p(s1) && storage_ram_p(s2)) {
862  ram r1 = storage_ram(s1);
863  ram r2 = storage_ram(s2);
864  entity f1 = ram_function(r1);
865  entity f2 = ram_function(r2);
866  entity a1 = ram_section(r1);
867  entity a2 = ram_section(r2);
868  const char* mn ;
869  const char* ln ;
870 
871  if(f1==f2)
872  mn = entity_local_name(f1);
873  else
874  mn = ANY_MODULE_NAME;
875 
876  if(static_area_p(a1) && static_area_p(a2))
878  else if(dynamic_area_p(a1) && dynamic_area_p(a2))
880  else if(stack_area_p(a1) && stack_area_p(a2))
882  else if(heap_area_p(a1) && heap_area_p(a2))
884  else
885  ln = ANYWHERE_LOCATION;
886  e = FindEntity(mn, ln);
887  }
888  else
889  pips_internal_error("not implemented");
890  }
891  }
892  return e;
893 }
entity variable_to_abstract_location(entity v)
returns the smallest abstract locations containing the location of variable v.
int f2(int off1, int off2, int w, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:1
bool dynamic_area_p(entity aire)
Definition: area.c:68
bool stack_area_p(entity aire)
Definition: area.c:104
bool static_area_p(entity aire)
Definition: area.c:77
#define storage_ram_p(x)
Definition: ri.h:2519
#define ram_section(x)
Definition: ri.h:2249
#define storage_ram(x)
Definition: ri.h:2521
#define ram_function(x)
Definition: ri.h:2247

References abstract_locations_max(), ANY_MODULE_NAME, ANYWHERE_LOCATION, DYNAMIC_AREA_LOCAL_NAME, dynamic_area_p(), entity_abstract_location_p(), entity_local_name(), entity_storage, entity_undefined, f2(), FindEntity(), HEAP_AREA_LOCAL_NAME, heap_area_p(), pips_internal_error, ram_function, ram_section, s1, STACK_AREA_LOCAL_NAME, stack_area_p(), STATIC_AREA_LOCAL_NAME, static_area_p(), storage_ram, storage_ram_p, and variable_to_abstract_location().

Referenced by effect_may_union(), effect_must_union(), and region_union().

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

◆ entity_nowhere_locations()

entity entity_nowhere_locations ( void  )

return ANY_MODULE:NOWHERE

Size and layout are unknown

Definition at line 174 of file anywhere_abstract_locations.c.

175 {
176  static entity nowhere = entity_undefined;
177  static const char any_name [] = ANY_MODULE_NAME MODULE_SEP_STRING NOWHERE_LOCATION ;
178  nowhere = gen_find_tabulated(any_name, entity_domain);
179  if(entity_undefined_p(nowhere)) {
180  area a = make_area(0,NIL); /* Size and layout are unknown */
181  type t = make_type_area(a);
182  nowhere = make_entity(strdup(any_name),
185  register_static_entity(&nowhere);
186  }
187 
188  return nowhere;
189 }
#define NOWHERE_LOCATION
void register_static_entity(entity *e)
add given entity to the set of entities that must reset upon workspace deletion practically,...
Definition: entity.c:156

References ABSTRACT_LOCATION, ANY_MODULE_NAME, entity_domain, entity_kind, entity_undefined, entity_undefined_p, gen_find_tabulated(), make_area(), make_entity, make_storage_rom(), make_type_area(), make_value_unknown(), MODULE_SEP_STRING, NIL, NOWHERE_LOCATION, register_static_entity(), and strdup().

Referenced by check_abstract_locations(), and entity_nowhere_locations_p().

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

◆ entity_nowhere_locations_p()

bool entity_nowhere_locations_p ( entity  e)

test if an entity is the bottom of the lattice

Should we care for the typed nowhere too?

Definition at line 200 of file anywhere_abstract_locations.c.

201 {
203 }

References entity_nowhere_locations(), and same_entity_p().

Referenced by check_abstract_locations(), gen_may_set(), gen_must_set(), opkill_may_name(), opkill_must_name(), reference_add_field_dimension(), and strict_constant_path_p().

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

◆ entity_null_locations()

entity entity_null_locations ( void  )

return TOP-LEVEL:NULL_POINTER The NULL pointer should be a global variable, unique for all modules FI: why isn't it called entity_null_location()?

Since NULL is a constant, it should be declared as a function. But then it cold not be used in a reference for the points-to analysis. Too bad for the semantics analysis of pointers were a constant 0-ary function would make more sense.

Size and layout are unknown

Definition at line 223 of file anywhere_abstract_locations.c.

224 {
225  static entity null_pointer = entity_undefined;
226  if(entity_undefined_p(null_pointer)) {
227  if(true) {
229  area a = make_area(0,NIL); /* Size and layout are unknown */
230  type t = make_type_area(a);
231  null_pointer = make_entity(strdup(null_name),
233  // FI: I do not see why NULL should be an abstract location; it
234  // does not represent a set of locations, but a unique one
235  // entity_kind(null_pointer) = ABSTRACT_LOCATION;
236  entity_kind(null_pointer) = DEFAULT_ENTITY_KIND;
237  }
238  else {
243  entity_type(null_pointer) = ft;
244  entity_storage(null_pointer) = make_storage_rom();
246  }
247  register_static_entity(&null_pointer);
248  }
249 
250  return null_pointer;
251 }
functional make_functional(list a1, type a2)
Definition: ri.c:1109
value make_value_constant(constant _field_)
Definition: ri.c:2841
type make_type_functional(functional _field_)
Definition: ri.c:2718
type make_type_void(list _field_)
Definition: ri.c:2727
constant make_constant_int(intptr_t _field_)
Definition: ri.c:409
#define NULL_POINTER_NAME
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
@ DEFAULT_ENTITY_KIND
type type_to_pointer_type(type)
allocate a new type "pt" which includes directly "t".
Definition: type.c:5253

References copy_type(), DEFAULT_ENTITY_KIND, entity_initial, entity_kind, entity_storage, entity_type, entity_undefined, entity_undefined_p, FindOrCreateEntity(), make_area(), make_constant_int(), make_entity, make_functional(), make_storage_rom(), make_type_area(), make_type_functional(), make_type_void(), make_value_constant(), make_value_unknown(), MODULE_SEP_STRING, NIL, NULL_POINTER_NAME, register_static_entity(), strdup(), TOP_LEVEL_MODULE_NAME, and type_to_pointer_type().

Referenced by check_abstract_locations(), entity_null_locations_p(), make_null_cell(), null_pointer_value_entity(), and points_to_null_sinks().

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

◆ entity_null_locations_p()

◆ entity_stub_sink_p()

bool entity_stub_sink_p ( entity  e)

test if an entity is a stub sink for a formal parameter e.g.

f->_f_1, EXACT

Definition at line 599 of file anywhere_abstract_locations.c.

600 {
601  bool stub_sink_p = false;
602  bool dummy_target_p = false;
603  const char * en = entity_local_name(e);
604  storage s = entity_storage(e);
605  if(storage_ram_p(s)) {
606  // dummy_target_p = pointer_dummy_targets_area_p(ram_section(storage_ram(s)));
607  dummy_target_p = formal_area_p(ram_section(storage_ram(s)));
608  }
609  char first = en[0];
610  //char penultimate = en[strlen(en) - 2];
611  int l = strlen(en);
612  if(dummy_target_p && first == '_') {
613  int i = 1;
614  while('0' <=en[l-i] && en[l-i]<='9') {
615  i++;
616  }
617  if(i>=2 && en[l-i]=='_')
618  stub_sink_p = true;
619  }
620 
621  return stub_sink_p;
622 }
bool formal_area_p(entity aire)
Definition: area.c:95

References entity_local_name(), entity_storage, formal_area_p(), ram_section, storage_ram, and storage_ram_p.

Referenced by cell_out_of_scope_p(), create_stub_entity(), expand_points_to_domain(), generic_atomic_points_to_reference_p(), generic_points_to_set_to_stub_cell_list(), generic_remove_unreachable_vertices_in_points_to_graph(), generic_transformer_to_analyzed_locations(), reference_to_points_to(), source_to_sinks(), strict_constant_path_p(), stub_entity_of_module_p(), stub_points_to_cell_p(), subscript_to_points_to_sinks(), and transformer_general_consistency_p().

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

◆ entity_typed_anywhere_locations()

entity entity_typed_anywhere_locations ( type  t)

Definition at line 111 of file anywhere_abstract_locations.c.

112 {
114 }

References ANYWHERE_LOCATION, and entity_all_xxx_locations_typed().

Referenced by abstract_locations_max(), binary_intrinsic_call_to_points_to_sinks(), cells_to_read_or_write_effects(), points_to_anywhere_sinks(), and reference_add_field_dimension().

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

◆ entity_typed_anywhere_locations_p()

bool entity_typed_anywhere_locations_p ( entity  e)

Test if an entity is the bottom of the lattice.

Not really since it is typed...

The typed anywhere locations have names like ANYWHERE_LOCATION_bxxx

Beware, because the string ANYWHERE_LOCATION is also used for the heap, HEAP**ANYWHERE.

Also, this does not check for the module: is it ANYMODULE or a specific module?

Definition at line 160 of file anywhere_abstract_locations.c.

161 {
162  bool typed_anywhere_p = false;
163  string ln = (string) entity_local_name(e);
164  string p = strstr(ln, ANYWHERE_LOCATION);
165  if(p==ln) {
166  // if the two strings are equal, we have the non-typed anywhere location
167  typed_anywhere_p = strcmp(ln, ANYWHERE_LOCATION);
168  }
169  return typed_anywhere_p;
170 }
char * string
STRING.
Definition: newgen_types.h:39

References ANYWHERE_LOCATION, and entity_local_name().

Referenced by analyzable_scalar_entity_p(), cells_to_read_or_write_effects(), effect_reference_dereferencing_p(), generic_anywhere_effect_p(), generic_atomic_points_to_reference_p(), module_to_value_mappings(), points_to_cell_translation(), reference_add_field_dimension(), reference_typed_anywhere_locations_p(), semantics_usable_points_to_reference_p(), source_to_sinks(), and strict_constant_path_p().

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

◆ entity_typed_nowhere_locations()

entity entity_typed_nowhere_locations ( type  t)

Definition at line 191 of file anywhere_abstract_locations.c.

192 {
194 }

References entity_all_xxx_locations_typed(), and NOWHERE_LOCATION.

+ Here is the call graph for this function:

◆ entity_typed_nowhere_locations_p()

bool entity_typed_nowhere_locations_p ( entity  e)

test if an entity is the bottom of the lattice

Definition at line 206 of file anywhere_abstract_locations.c.

207 {
208  string ln = (string) entity_local_name(e);
209  string p = strstr(ln, NOWHERE_LOCATION);
210  return p!=NULL;
211 }

References entity_local_name(), and NOWHERE_LOCATION.

Referenced by any_basic_update_to_transformer(), any_update_to_transformer(), gen_may_set(), gen_must_set(), generic_atomic_points_to_reference_p(), nowhere_cell_p(), points_to_unary_operation_to_transformer(), reference_add_field_dimension(), semantics_usable_points_to_reference_p(), strict_constant_path_p(), and text_points_to_relation().

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

◆ environment_effect_p()

bool environment_effect_p ( effect  e)

Definition at line 1071 of file effects.c.

1072 {
1073  action a = effect_action(e);
1075  bool env_p = action_kind_environment_p(ak);
1076 
1077  return env_p;
1078 }

References action_kind_environment_p, action_read, action_read_p, action_write, and effect_action.

Referenced by find_effect_actions_for_entity().

+ Here is the caller graph for this function:

◆ error_reset_pt_to_list()

void error_reset_pt_to_list ( void  )

◆ exact_points_to_subscript_list_p()

bool exact_points_to_subscript_list_p ( list  sl)

See if the subscript list sl is precise, i.e.

if is does not contain any unbounded expression.

It is assumed that it is a points-to subscript list. Each subscript is either an integer constant, or a field reference or an unbounded expression.

This function may have been defined several times...

Parameters
sll

Definition at line 1027 of file points_to.c.

1028 {
1029  bool exact_p = true;
1030  FOREACH(EXPRESSION, s, sl) {
1031  if(unbounded_expression_p(s)) {
1032  exact_p = false;
1033  break;
1034  }
1035  }
1036  return exact_p;
1037 }

References EXPRESSION, FOREACH, and unbounded_expression_p().

+ Here is the call graph for this function:

◆ field_reference_expression_p()

bool field_reference_expression_p ( expression  e)

Check if expression "e" is a reference to a struct field.

Definition at line 224 of file points_to.c.

225 {
226  bool field_p = false;
227  syntax s = expression_syntax(e);
228  if(syntax_reference_p(s)) {
231  field_p = entity_field_p(f);
232  }
233  return field_p;
234 }

References entity_field_p(), expression_syntax, f(), reference_variable, syntax_reference, and syntax_reference_p.

Referenced by points_to_array_reference_p(), points_to_array_reference_to_type(), points_to_reference_to_final_dimension(), points_to_reference_update_final_subscripts(), and reduce_cell_to_pointer_type().

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

◆ FILE_star_effect_reference_p()

bool FILE_star_effect_reference_p ( reference  ref)
Parameters
refef

Definition at line 536 of file effects.c.

537 {
538  bool res = false;
540  pips_debug(8, "begin with type %s\n", string_of_type(t));
541  if (type_variable_p(t))
542  {
544  if (basic_pointer_p(b))
545  {
546  t = basic_pointer(b);
547  if (type_variable_p(t))
548  {
550  if (basic_derived_p(b))
551  {
552  entity te = basic_derived(b);
553  if (same_string_p(entity_user_name(te), "_IO_FILE"))
554  {
555  res = true;
556  }
557  }
558  }
559  }
560  }
561  pips_debug(8, "end with : %s\n", res? "true":"false");
562  return res;
563 }
string string_of_type(const type)
Definition: type.c:56

References basic_derived, basic_derived_p, basic_pointer, basic_pointer_p, entity_basic_concrete_type(), entity_user_name(), pips_debug, ref, reference_variable, same_string_p, string_of_type(), type_variable, type_variable_p, and variable_basic.

Referenced by create_step_regions().

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

◆ find_points_to_subscript_for_type()

list find_points_to_subscript_for_type ( cell  c,
type  t 
)

Find the subscript in the reference of cell "c" that would make the reference type be "t" if the subscript list were truncated just after it.

Select the longest possible subscript list.

Core dump if it is not possible.

No smart implementation: trial and error (probably already implemented somewhere else.

Let's try to add a zero subscript instead...

For the time being, no need to restore the reference in case of failure.

Definition at line 1274 of file type.c.

1275 {
1276  list csl = list_undefined;
1278  entity v = reference_variable(r);
1279  type rt = points_to_reference_to_concrete_type(r); // reference type
1280  list sl = reference_indices(r); // subscript list
1281  list rsl = gen_nreverse(sl); // temporary side-effect on "r" (and "c")
1282  list crsl = rsl; // current reverse subscript list
1283 
1284  while(!array_pointer_type_equal_p(t, rt) && !ENDP(crsl)) {
1285  POP(crsl);
1286  list nsl = gen_copy_seq(crsl);
1287  reference nr = make_reference(v, nsl);
1289  reference_indices(nr) = NIL;
1290  free_reference(nr);
1291  }
1292 
1294 
1295  if(!ENDP(crsl)) {
1296  csl = crsl;
1297  }
1298  else {
1299  if(array_pointer_type_equal_p(t, rt)) {
1300  // dereferencing18.c: only one element is allocated. 0 is the
1301  // only possible subscript;
1302  csl = NIL; // ==crsl
1303  }
1304  else {
1305  /* Let's try to add a zero subscript instead... */
1307  list nsl = CONS(EXPRESSION, z, NIL);
1308  /* For the time being, no need to restore the reference in case of
1309  failure. */
1312  if(array_pointer_type_equal_p(t, rt))
1313  csl = nsl;
1314  else
1315  pips_internal_error("Type t and reference r are incompatible.\n");
1316  }
1317  }
1318 
1319  return csl;
1320 }
type points_to_reference_to_concrete_type(reference r)
Definition: type.c:685
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
expression make_zero_expression(void)
Make a zero expression.
Definition: expression.c:1212

References array_pointer_type_equal_p(), cell_any_reference(), CONS, ENDP, EXPRESSION, free_reference(), gen_copy_seq(), gen_nconc(), gen_nreverse(), list_undefined, make_reference(), make_zero_expression(), NIL, pips_internal_error, points_to_reference_to_concrete_type(), POP, reference_indices, and reference_variable.

Referenced by offset_points_to_cell().

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

◆ formal_parameter_points_to_cell_p()

bool formal_parameter_points_to_cell_p ( cell  c)

Definition at line 99 of file points_to.c.

100 {
101  bool formal_p = true;
103  entity v = reference_variable(r);
104  formal_p = formal_parameter_p(v);
105  return formal_p;
106 }
bool formal_parameter_p(entity)
Definition: variable.c:1489

References cell_any_reference(), formal_parameter_p(), and reference_variable.

Referenced by points_to_to_context_points_to().

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

◆ fprint_points_to_cell()

void fprint_points_to_cell ( FILE *  ,
cell   
)

◆ full_action_to_short_string()

string full_action_to_short_string ( action  ac)
Parameters
acc

Definition at line 969 of file effects.c.

970 {
971  string s = string_undefined;
972  if(action_read_p(ac)) {
973  action_kind ak = action_read(ac);
974 
975  if(action_kind_store_p(ak))
976  s = "R";
977  else if(action_kind_environment_p(ak))
978  s = "RE";
979  else if(action_kind_type_declaration_p(ak))
980  s = "RT";
981  }
982  else {
983  action_kind ak = action_write(ac);
984 
985  if(action_kind_store_p(ak))
986  s = "W";
987  else if(action_kind_environment_p(ak))
988  s = "WE";
989  else if(action_kind_type_declaration_p(ak))
990  s = "WT";
991  }
992  return s;
993 }

References action_kind_environment_p, action_kind_store_p, action_kind_type_declaration_p, action_read, action_read_p, action_write, and string_undefined.

Referenced by conflicts_sort_callback(), prettyprint_dependence_graph(), and prettyprint_dot_dependence_graph().

+ Here is the caller graph for this function:

◆ full_action_to_string()

string full_action_to_string ( action  ac)
Parameters
acc

Definition at line 943 of file effects.c.

944 {
945  string s = string_undefined;
946  if(action_read_p(ac)) {
947  action_kind ak = action_read(ac);
948 
949  if(action_kind_store_p(ak))
950  s = "read memory";
951  else if(action_kind_environment_p(ak))
952  s = "read environment";
953  else if(action_kind_type_declaration_p(ak))
954  s = "read type";
955  }
956  else {
957  action_kind ak = action_write(ac);
958 
959  if(action_kind_store_p(ak))
960  s = "write memory";
961  else if(action_kind_environment_p(ak))
962  s = "write environment";
963  else if(action_kind_type_declaration_p(ak))
964  s = "write type";
965  }
966  return s;
967 }

References action_kind_environment_p, action_kind_store_p, action_kind_type_declaration_p, action_read, action_read_p, action_write, and string_undefined.

◆ generic_atomic_points_to_cell_p()

bool generic_atomic_points_to_cell_p ( cell  c,
bool  strict_p 
)

Is it a unique concrete memory location?

If strict_p, stubs are not considered atomic, as is the case in an interprocedural setting since they can be associated to several cells in the caller frame.

Else, stubs are not considered non atomic per se.

Parameters
strict_ptrict_p

Definition at line 452 of file points_to.c.

453 {
455  bool atomic_p = null_cell_p(c)
456  || generic_atomic_points_to_reference_p(r, strict_p);
457 
458  return atomic_p;
459 }

References cell_any_reference(), generic_atomic_points_to_reference_p(), and null_cell_p().

Referenced by add_implicitly_killed_arcs_to_kill_set(), freed_list_to_points_to(), list_assignment_to_points_to(), and upgrade_approximations_in_points_to_set().

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

◆ generic_atomic_points_to_reference_p()

bool generic_atomic_points_to_reference_p ( reference  r,
bool  strict_p 
)

Is it a unique concrete memory location?

No, if it is a reference to an abstract location.

No, if the subscripts include an unbounded expression.

Very preliminary version. One of the keys to Amira Mensi's work.

More about stubs: a stub is not NULL but there is no information to know if they represent one address or a set of addresses. Unless the intraprocedural points-to analysis is performed for each combination of atomic/non-atomic stub, safety implies that stub-based references are not atomic (strict_p=true). In some other cases, you know that a stub does represent a unique location (strict_p=false).

Note: it is assumed that the reference is a points-to reference. All subscripts are constants, field references or unbounded expressions.

Note: FI, I have a probleme when calling this function from a proper effects environment. In that case, stubs might be assumed to be unique memory locations. The exactness information can be derived from the numer of targets in the matching list.

Note 2: FI, I do not understand why the type of the reference is not taken into account.

Parameters
strict_ptrict_p

Definition at line 489 of file points_to.c.

490 {
491  bool atomic_p = false;
492  entity v = reference_variable(r);
493 
494  if(!entity_null_locations_p(v) // FI: NULL is considered atomic
498  && !entity_heap_location_p(v)) {
499  list sl = reference_indices(r);
500  //entity v = reference_variable(r);
501  if(!entity_stub_sink_p(v) || !strict_p) {
502  atomic_p = true;
503  FOREACH(EXPRESSION, se, sl) {
504  if(unbounded_expression_p(se)) {
505  atomic_p = false;
506  break;
507  }
508  else if(expression_range_p(se)) {
509  atomic_p = false;
510  break;
511  }
512  }
513  }
514  }
515 
516  return atomic_p;
517 }
bool entity_heap_location_p(entity b)
package abstract location.
bool entity_stub_sink_p(entity e)
test if an entity is a stub sink for a formal parameter e.g.
bool entity_anywhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool entity_typed_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool expression_range_p(expression e)
Definition: expression.c:1848

References entity_anywhere_locations_p(), entity_heap_location_p(), entity_null_locations_p(), entity_stub_sink_p(), entity_typed_anywhere_locations_p(), entity_typed_nowhere_locations_p(), EXPRESSION, expression_range_p(), FOREACH, reference_indices, reference_variable, and unbounded_expression_p().

Referenced by analyzed_reference_p(), atomic_points_to_reference_p(), create_values_for_simple_effect(), generic_atomic_points_to_cell_p(), generic_transform_sink_cells_from_matching_list(), and substitute_stubs_in_transformer_with_translation_binding().

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

◆ generic_entity_typed_anywhere_locations()

entity generic_entity_typed_anywhere_locations ( type  t)

Definition at line 116 of file anywhere_abstract_locations.c.

117 {
119  if(get_bool_property("ALIASING_ACROSS_TYPES"))
120  a = entity_all_locations();
121  else
123  return a;
124 }

References ANYWHERE_LOCATION, entity_all_locations(), entity_all_xxx_locations_typed(), entity_undefined, and get_bool_property().

+ Here is the call graph for this function:

◆ get_pt_to_list()

statement_points_to get_pt_to_list ( void  )

Referenced by generic_points_to_analysis().

+ Here is the caller graph for this function:

◆ heap_cell_p()

◆ heap_effect()

effect heap_effect ( entity  m,
action  ac 
)
Parameters
acc

Definition at line 391 of file effects.c.

392 {
394  effect any = effect_undefined;
395 
396  if(entity_undefined_p(heap)) {
397  pips_internal_error("Heap for module \"%s\" not found", entity_name(m));
398  }
399 
401  ac,
404 
405  return any;
406 }

References effect_undefined, entity_local_name(), entity_name, entity_undefined_p, FindEntity(), HEAP_AREA_LOCAL_NAME, make_approximation_may(), make_cell_reference(), make_descriptor_none(), make_effect(), make_reference(), NIL, and pips_internal_error.

+ Here is the call graph for this function:

◆ heap_effect_p()

bool heap_effect_p ( effect  e)

Definition at line 408 of file effects.c.

409 {
410  bool heap_p;
412  entity v = reference_variable(r);
413 
415 
416  return heap_p;
417 }

References effect_any_reference, entity_local_name(), HEAP_AREA_LOCAL_NAME, reference_variable, and same_string_p.

+ Here is the call graph for this function:

◆ init_pt_to_list()

void init_pt_to_list ( void  )

Referenced by generic_points_to_analysis().

+ Here is the caller graph for this function:

◆ io_cell_p()

bool io_cell_p ( cell  c)

Definition at line 506 of file effects.c.

507 {
509 }
bool io_effect_entity_p(entity e)
Definition: effects.c:496

References cell_any_reference(), io_effect_entity_p(), and reference_variable.

+ Here is the call graph for this function:

◆ io_effect_entity_p()

bool io_effect_entity_p ( entity  e)

Definition at line 496 of file effects.c.

497 {
498  return io_luns_entity_p(e);
499 }
bool io_luns_entity_p(entity e)
Definition: entity.c:1146

References io_luns_entity_p().

Referenced by io_cell_p(), io_effect_p(), io_efficient_compile(), pure_function_p(), and safe_effects_for_reductions().

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

◆ io_effect_p()

bool io_effect_p ( effect  e)

Definition at line 501 of file effects.c.

References effect_any_reference, io_effect_entity_p(), and reference_variable.

Referenced by create_step_regions(), do_check_isolate_statement_preconditions_on_call(), effects_to_dma(), guard_expanded_statement_if_needed(), io_effects_p(), and potential_out_effects_p().

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

◆ io_effects_p()

bool io_effects_p ( list  effects)

Definition at line 512 of file effects.c.

513 {
514  FOREACH(EFFECT,eff,effects)
515  if(io_effect_p(eff)) return true;
516  return false;
517 }
bool io_effect_p(effect e)
Definition: effects.c:501

References EFFECT, FOREACH, and io_effect_p().

+ Here is the call graph for this function:

◆ is_inferior_cell_descriptor_pvarval()

int is_inferior_cell_descriptor_pvarval ( Pvecteur pvarval1,
Pvecteur pvarval2 
)

weight function for Pvecteur passed as argument to sc_lexicographic_sort in prettyprint functions involving cell descriptors.

The strange argument type is required by qsort(), deep down in the calls. This function is an adaptation of is_inferior_pvarval in semantics

The constant term is given the highest weight to push constant terms at the end of the constraints and to make those easy to compare. If not, constant 0 will be handled differently from other constants. However, it would be nice to give constant terms the lowest weight to print simple constraints first...

Either I define two comparison functions, or I cheat somewhere else. Let's cheat?

Parameters
pvarval1varval1
pvarval2varval2

Definition at line 305 of file compare.c.

306 {
307  /* The constant term is given the highest weight to push constant
308  terms at the end of the constraints and to make those easy
309  to compare. If not, constant 0 will be handled differently from
310  other constants. However, it would be nice to give constant terms
311  the lowest weight to print simple constraints first...
312 
313  Either I define two comparison functions, or I cheat somewhere else.
314  Let's cheat? */
315  int is_equal = 0;
316 
317  if (term_cst(*pvarval1) && !term_cst(*pvarval2))
318  is_equal = 1;
319  else if (term_cst(*pvarval1) && term_cst(*pvarval2))
320  is_equal = 0;
321  else if(term_cst(*pvarval2))
322  is_equal = -1;
323  else if(variable_phi_p((entity) vecteur_var(*pvarval1))
324  && !variable_phi_p((entity) vecteur_var(*pvarval2)))
325  is_equal = -1;
326  else if(variable_phi_p((entity) vecteur_var(*pvarval2))
327  && !variable_phi_p((entity) vecteur_var(*pvarval1)))
328  is_equal = 1;
329  else
330  is_equal =
331  strcmp(entity_name((entity) vecteur_var(*pvarval1)),
332  entity_name((entity) vecteur_var(*pvarval2)));
333 
334  return is_equal;
335 }
#define variable_phi_p(e)
true if e is a phi variable PHI entities have a name like: REGIONS:PHI#, where # is a number.
#define vecteur_var(v)
#define term_cst(varval)

References entity_name, term_cst, variable_phi_p, and vecteur_var.

Referenced by text_pointer_value(), and text_points_to_relation().

+ Here is the caller graph for this function:

◆ list_to_effects()

effects list_to_effects ( list  l_eff)

Future API for GAP, Generic Access Path.


list-effects conversion functions


Parameters
l_eff_eff

Definition at line 202 of file effects.c.

204 {
205  effects res = make_effects(l_eff);
206  return res;
207 }
effects make_effects(list a)
Definition: effects.c:568

References make_effects().

Referenced by listmap_to_effectsmap().

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

◆ listmap_to_effectsmap()

statement_mapping listmap_to_effectsmap ( statement_mapping  l_map)
Parameters
l_map_map

Definition at line 216 of file effects.c.

218 {
220 
221  STATEMENT_MAPPING_MAP(s,val,{
222  hash_put((hash_table) efs_map, (char *) s, (char *) list_to_effects((list) val));
223  }, l_map);
224 
225  return efs_map;
226 }
effects list_to_effects(list l_eff)
Future API for GAP, Generic Access Path.
Definition: effects.c:202

References hash_put(), list_to_effects(), MAKE_STATEMENT_MAPPING, and STATEMENT_MAPPING_MAP.

+ Here is the call graph for this function:

◆ load_pt_to_list()

◆ location_entity_of_module_p()

bool location_entity_of_module_p ( entity  le,
entity  m 
)
Parameters
lee

Definition at line 360 of file locations.c.

361 {
362  bool location_p = false;
363  if(!entity_undefined_p(le)) {
364  value v = entity_initial(le);
365  if(!value_undefined_p(v))
366  if(value_reference_p(v))
367  // FI: could be checked with a pointer equality via the storage field
368  location_p = strcmp(entity_module_name(le), entity_user_name(m))==0;
369  }
370  return location_p;
371 }

References entity_initial, entity_module_name(), entity_undefined_p, entity_user_name(), value_reference_p, and value_undefined_p.

Referenced by clean_up_points_to_stubs().

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

◆ location_entity_p()

bool location_entity_p ( entity  le)
Parameters
lee

Definition at line 349 of file locations.c.

350 {
351  bool location_p = false;
352  if(!entity_undefined_p(le)) {
353  value v = entity_initial(le);
354  if(!value_undefined_p(v))
355  location_p = value_reference_p(v);
356  }
357  return location_p;
358 }

References entity_initial, entity_undefined_p, value_reference_p, and value_undefined_p.

Referenced by entities_maymust_conflict_p(), generic_effects_maymust_read_or_write_scalar_entity_p(), generic_reference_to_transformer(), module_to_value_mappings(), points_to_cells_parameters(), transformer_formal_parameter_projection(), and value_passing_summary_transformer().

+ Here is the caller graph for this function:

◆ make_action_read_memory()

action make_action_read_memory ( void  )

Definition at line 1017 of file effects.c.

1018 {
1020  return a;
1021 }
action make_action_read(action_kind _field_)
Definition: effects.c:123
action_kind make_action_kind_store(void)
Definition: effects.c:65

References make_action_kind_store(), and make_action_read().

Referenced by c_convex_effects_on_formal_parameter_backward_translation(), call_to_post_pv(), cells_to_read_or_write_effects(), check_for_effected_statement(), create_step_regions(), expression_to_post_pv(), live_out_paths_from_loop_to_body(), and real_regions_forward_translation().

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

◆ make_action_write_memory()

◆ make_address_of_pointer_value()

cell_relation make_address_of_pointer_value ( cell  c1,
cell  c2,
tag  app_tag,
descriptor  d 
)
Parameters
c11
c22
app_tagpp_tag

Definition at line 142 of file pointer_values.c.

143 {
146  cell_relation pv = make_cell_relation(ic1, ic2, make_approximation(app_tag, UU), d);
147  return(pv);
148 }
cell_relation make_cell_relation(interpreted_cell a1, interpreted_cell a2, approximation a3, descriptor a4)
Definition: effects.c:341
interpreted_cell make_interpreted_cell(cell a1, cell_interpretation a2)
Definition: effects.c:709
cell_interpretation make_cell_interpretation_value_of(void)
Definition: effects.c:237
cell_interpretation make_cell_interpretation_address_of(void)
Definition: effects.c:240
approximation make_approximation(enum approximation_utype tag, void *val)
Definition: effects.c:176

References make_approximation(), make_cell_interpretation_address_of(), make_cell_interpretation_value_of(), make_cell_relation(), make_interpreted_cell(), and UU.

Referenced by make_anywhere_anywhere_pvs(), make_simple_pv_from_simple_effects(), module_initial_parameter_pv(), simple_pv_may_union(), simple_pv_must_union(), and simple_pv_translate().

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

◆ make_anywhere_cell()

cell make_anywhere_cell ( type  t)

Definition at line 1028 of file anywhere_abstract_locations.c.

1029 {
1031  cell sc = make_cell_reference(r);
1032  return sc;
1033 }
reference make_anywhere_reference(type t)
This function should be located somewhere in effect-util in or near abstract locations.

References make_anywhere_reference(), and make_cell_reference().

Referenced by binary_intrinsic_call_to_points_to_sinks(), generic_transform_sink_cells_from_matching_list(), k_limit_points_to(), sizeofexpression_to_points_to_sinks(), source_to_sinks(), struct_assignment_to_points_to(), struct_initialization_to_points_to(), unary_intrinsic_call_to_points_to_sinks(), and use_default_sink_cell().

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

◆ make_anywhere_points_to_cell()

cell make_anywhere_points_to_cell ( type  t)

Function storing points to information attached to a statement.

Generate a global variable holding a statement_points_to, a mapping from statements to lists of points-to arcs. The variable is called "pt_to_list_object".

The macro also generates a set of functions used to deal with this global variables.

The functions are defined in newgen_generic_function.h:

pt_to_list_undefined_p()

reset_pt_to_list()

error_reset_pt_to_list()

set_pt_to_list(o)

get_pt_to_list()

store_pt_to_list(k, v)

update_pt_to_list(k, v)

load_pt_to_list(k)

delete_pt_to_list(k)

bound_pt_to_list_p(k)

store_or_update_pt_to_list(k, v) Functions specific to points-to analysis

Definition at line 87 of file points_to.c.

88 {
90  if(get_bool_property("ALIASING_ACROSS_TYPES"))
92  else
96  return c;
97 }

References ANYWHERE_LOCATION, entity_all_locations(), entity_all_xxx_locations_typed(), entity_undefined, get_bool_property(), make_cell_reference(), make_reference(), and NIL.

Referenced by anywhere_source_to_sinks(), assignment_to_points_to(), gen_may_set(), gen_must_set(), list_assignment_to_points_to(), points_to_cells_minimal_upper_bound(), process_casted_sinks(), process_casted_sources(), semantics_expression_to_points_to_sinks(), and source_to_sinks().

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

◆ make_anywhere_reference()

reference make_anywhere_reference ( type  t)

This function should be located somewhere in effect-util in or near abstract locations.

Definition at line 1016 of file anywhere_abstract_locations.c.

1017 {
1018  bool type_sensitive_p = !get_bool_property("ALIASING_ACROSS_TYPES");
1019  entity anywhere = type_sensitive_p?
1021  :
1023 
1024  reference r = make_reference(anywhere,NIL);
1025  return r;
1026 }

References ANYWHERE_LOCATION, entity_all_xxx_locations(), entity_all_xxx_locations_typed(), get_bool_property(), make_reference(), and NIL.

Referenced by binary_intrinsic_call_to_points_to_sinks(), generic_eval_cell_with_points_to(), and make_anywhere_cell().

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

◆ make_location_entity()

entity make_location_entity ( reference  cp)

locations.c

Add the new entity to the module declarations

Parameters
cpp

Definition at line 274 of file locations.c.

275 {
276  entity elhs = reference_variable(cp);
277 
279  // Evaluation the constant subscript expressions such as a[4/2]
281  string cp_name = constant_memory_access_path_to_location_name(ncp);
282 
283  // Do not make the same entity twice
284  entity ecp = gen_find_entity(cp_name);
285  if(entity_undefined_p(ecp)) {
286  ecp = make_entity(
287  strdup(cp_name),
288  copy_type(t),
290  make_value_reference(ncp));
291 
292  /* Add the new entity to the module declarations */
293  string mn = (string) entity_module_name(elhs);
295  value val = entity_initial(m);
296  if(value_code_p(val)) {
297  code c = value_code(val);
298  code_declarations(c) =
299  CONS(ENTITY, ecp, code_declarations(c));
300  }
301  else
302  pips_internal_error("Module entity \"%s\" is not a module.\n",
303  entity_name(m));
304  }
305  else {
306  free_reference(ncp);
307  }
308 
309  // FI: if this is useful to maintain the intermediate
310  // representation, then the module owning ecp should be computed. It
311  // does not have to be the current module.
312 
313  // AddEntityToCurrentModuleWithoutDeclaration(ecp);
314 
315  return ecp;
316 }
value make_value_reference(reference _field_)
Definition: ri.c:2853
storage copy_storage(storage p)
STORAGE.
Definition: ri.c:2228
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
#define value_code_p(x)
Definition: ri.h:3065
#define code_declarations(x)
Definition: ri.h:784
#define value_code(x)
Definition: ri.h:3067

References code_declarations, CONS, constant_memory_access_path_to_location_name(), constant_reference_to_normalized_constant_reference(), copy_storage(), copy_type(), cp, ENTITY, entity_initial, entity_module_name(), entity_name, entity_storage, entity_undefined_p, free_reference(), gen_find_entity(), make_entity, make_value_reference(), module_name_to_entity(), pips_internal_error, points_to_reference_to_concrete_type(), reference_variable, strdup(), value_code, and value_code_p.

Referenced by add_inter_or_intraprocedural_field_entities(), add_reference_values(), and module_to_value_mappings().

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

◆ make_null_pointer_value_cell()

cell make_null_pointer_value_cell ( void  )

Definition at line 93 of file pointer_values.c.

94 {
97 }
entity null_pointer_value_entity()

References make_cell_reference(), make_reference(), NIL, and null_pointer_value_entity().

Referenced by call_to_post_pv(), expression_to_post_pv(), null_to_sinks(), pointer_formal_parameter_to_stub_points_to(), and reference_condition_to_points_to().

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

◆ make_sensitivity_information()

sensitivity_information make_sensitivity_information ( statement  current_stmt,
entity  current_module,
list  enclosing_flow 
)
Parameters
current_stmturrent_stmt
current_moduleurrent_module
enclosing_flownclosing_flow

Definition at line 522 of file abstract_location.c.

525 {
529  si.enclosing_flow = enclosing_flow;
530  return si;
531 }
static string current_module
Definition: message.c:63
static statement current_stmt

References sensitivity_information::current_module, current_module, current_stmt, sensitivity_information::current_stmt, and sensitivity_information::enclosing_flow.

Referenced by flow_sensitive_malloc_to_points_to_sinks(), heap_intrinsic_to_post_pv(), and original_malloc_to_abstract_location().

+ Here is the caller graph for this function:

◆ make_undefined_pointer_value_cell()

cell make_undefined_pointer_value_cell ( void  )

Definition at line 62 of file pointer_values.c.

63 {
66 }
entity undefined_pointer_value_entity()
pointer_values.c

References make_cell_reference(), make_reference(), NIL, and undefined_pointer_value_entity().

Referenced by expression_to_post_pv(), free_to_post_pv(), make_simple_pv_from_simple_effects(), and pointer_values_remove_var().

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

◆ make_value_of_pointer_value()

cell_relation make_value_of_pointer_value ( cell  c1,
cell  c2,
tag  app_tag,
descriptor  d 
)
Parameters
c11
c22
app_tagpp_tag

Definition at line 129 of file pointer_values.c.

130 {
134 
136  pv = make_cell_relation(ic2, ic1, make_approximation(app_tag, UU), d);
137  else
138  pv = make_cell_relation(ic1, ic2, make_approximation(app_tag, UU), d);
139  return(pv);
140 }
bool null_pointer_value_cell_p(cell c)
bool undefined_pointer_value_cell_p(cell c)

References cell_relation_undefined, make_approximation(), make_cell_interpretation_value_of(), make_cell_relation(), make_interpreted_cell(), null_pointer_value_cell_p(), undefined_pointer_value_cell_p(), and UU.

Referenced by kill_pointer_value(), make_simple_pv_from_simple_effects(), and simple_pv_translate().

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

◆ malloc_arg_to_type()

type malloc_arg_to_type ( expression  e)

generate the type of the allocated area from the malloc argument

Parameters
eis the malloc argument expression
Returns
a new type (no sharing)

Store dependent types are not generated. It means that whenever the size of the allocated space is store dependent, the returned type is an array of unbounded_dimension.

which one is the sizeof operator ? try the second one first

sizeofexpression is an expression

Definition at line 187 of file abstract_location.c.

188 {
189  type t = type_undefined;
190  syntax s = expression_syntax(e);
193  bool scalar_p = false;;
194 
195  pips_debug(5, "begin for expression:%s\n", expression_to_string(e));
196 
198  {
199  scalar_p = true; // Not necessarily! An array type may be argument
200  sizeof_exp = syntax_sizeofexpression(s);
201  }
202  else if(syntax_cast_p(s)) {
203  cast c = syntax_cast(s);
204  expression ce = cast_expression(c);
205  t = malloc_arg_to_type(ce);
206  return t; // FI: I hate doing this...
207  }
208  else if (syntax_call_p(s))
209  {
210  call c = syntax_call(s);
211  entity func = call_function(c);
212  list func_args = call_arguments(c);
213 
215  {
216  pips_debug(5, "multiply operator found\n");
217  expression arg1 = EXPRESSION(CAR(func_args));
218  expression arg2 = EXPRESSION(CAR(CDR(func_args)));
219 
220  /* which one is the sizeof operator ? try the second one first */
222  {
223  pips_debug(5," second arg is a sizeof expression\n");
224  sizeof_exp = syntax_sizeofexpression(expression_syntax(arg2));
225  n = make_op_exp("-", copy_expression(arg1), int_to_expression(1));
226  }
228  {
229  pips_debug(5," first arg is a sizeof expression\n");
230  sizeof_exp = syntax_sizeofexpression(expression_syntax(arg1));
231  n = make_op_exp("-", copy_expression(arg2), int_to_expression(1));
232  }
233  else
234  {
236  }
237  }
238  else
239  {
241  }
242  }
243  else
245 
247  && !expression_constant_p(n))
248  {
249  // FI: I do not see why we cannot generate dependent types...
250  // We would have to be careful to evaluate the expression in
251  // case its variables are modified. Just as the parser should do.
252  pips_debug(5, "non constant number of elements "
253  "-> generating unbounded dimension\n");
254  free_expression(n);
256  }
257 
258  if (sizeofexpression_undefined_p(sizeof_exp))
259  {
262  CONS(DIMENSION,
264  NIL),
265  NIL));
266  }
267  else if (sizeofexpression_type_p(sizeof_exp))
268  {
269  type t_sizeof_exp = sizeofexpression_type(sizeof_exp);
270  variable t_var_sizeof_exp = type_variable_p(t_sizeof_exp) ?
271  type_variable(t_sizeof_exp) : variable_undefined;
272  pips_assert("type must be variable",
273  !variable_undefined_p(t_var_sizeof_exp));
274 
275  if (scalar_p)
277  (make_variable(copy_basic(variable_basic(t_var_sizeof_exp)),
279  (t_var_sizeof_exp)),
280  NIL));
281  else
283  (make_variable(copy_basic(variable_basic(t_var_sizeof_exp)),
284  CONS(DIMENSION,
287  (t_var_sizeof_exp))),
288  NIL));
289  }
290  else /* sizeofexpression is an expression */
291  {
292  type t_sizeof_exp =
294  variable t_var_sizeof_exp = type_variable_p(t_sizeof_exp) ?
295  type_variable(t_sizeof_exp) : variable_undefined;
296 
297  if (scalar_p)
299  (make_variable(copy_basic(variable_basic( t_var_sizeof_exp)),
301  (t_var_sizeof_exp)),
302  NIL));
303  else
305  (make_variable(copy_basic(variable_basic(t_var_sizeof_exp)),
306  CONS(DIMENSION,
309  (t_var_sizeof_exp))),
310  NIL));
311  free_type(t_sizeof_exp);
312  }
313  pips_debug(5, "end with type %s\n", string_of_type(t));
314  return t;
315 }
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
basic make_basic_int(intptr_t _field_)
Definition: ri.c:158
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
type malloc_arg_to_type(expression e)
generate the type of the allocated area from the malloc argument
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
#define DEFAULT_CHARACTER_TYPE_SIZE
Default type sizes.
#define MULTIPLY_OPERATOR_NAME
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
#define call_function(x)
Definition: ri.h:709
#define sizeofexpression_type(x)
Definition: ri.h:2406
#define syntax_call_p(x)
Definition: ri.h:2734
#define sizeofexpression_expression(x)
Definition: ri.h:2409
#define syntax_cast(x)
Definition: ri.h:2739
#define syntax_sizeofexpression_p(x)
Definition: ri.h:2740
#define cast_expression(x)
Definition: ri.h:747
#define expression_undefined
Definition: ri.h:1223
#define variable_undefined
Definition: ri.h:3095
#define sizeofexpression_undefined_p(x)
Definition: ri.h:2371
#define syntax_sizeofexpression(x)
Definition: ri.h:2742
#define variable_undefined_p(x)
Definition: ri.h:3096
#define sizeofexpression_type_p(x)
Definition: ri.h:2404
#define syntax_call(x)
Definition: ri.h:2736
#define expression_undefined_p(x)
Definition: ri.h:1224
#define sizeofexpression_undefined
Definition: ri.h:2370
#define call_arguments(x)
Definition: ri.h:711
#define syntax_cast_p(x)
Definition: ri.h:2737

References call_arguments, call_function, CAR, cast_expression, CDR, CONS, copy_basic(), copy_expression(), DEFAULT_CHARACTER_TYPE_SIZE, DIMENSION, entity_local_name(), EXPRESSION, expression_constant_p(), expression_syntax, expression_to_string(), expression_to_type(), expression_undefined, expression_undefined_p, free_expression(), free_type(), gen_full_copy_list(), int_to_expression(), make_basic_int(), make_dimension(), make_op_exp(), make_type_variable(), make_unbounded_expression(), make_variable(), MULTIPLY_OPERATOR_NAME, NIL, pips_assert, pips_debug, same_string_p, sizeofexpression_expression, sizeofexpression_type, sizeofexpression_type_p, sizeofexpression_undefined, sizeofexpression_undefined_p, string_of_type(), syntax_call, syntax_call_p, syntax_cast, syntax_cast_p, syntax_sizeofexpression, syntax_sizeofexpression_p, type_undefined, type_variable, type_variable_p, unbounded_expression_p(), variable_basic, variable_dimensions, variable_undefined, and variable_undefined_p.

Referenced by malloc_to_abstract_location().

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

◆ malloc_cell_p()

bool malloc_cell_p ( cell  c)

Definition at line 483 of file effects.c.

484 {
486 }
bool malloc_effect_entity_p(entity e)
Definition: entity.c:1158

References cell_entity(), and malloc_effect_entity_p().

+ Here is the call graph for this function:

◆ malloc_effect_p()

bool malloc_effect_p ( effect  e)

Definition at line 478 of file effects.c.

479 {
481 }

References effect_entity(), and malloc_effect_entity_p().

Referenced by set_add_scalars().

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

◆ malloc_reference_p()

bool malloc_reference_p ( reference  r)

Definition at line 488 of file effects.c.

489 {
491 }

References malloc_effect_entity_p(), and reference_variable.

+ Here is the call graph for this function:

◆ malloc_to_abstract_location()

entity malloc_to_abstract_location ( expression  malloc_exp,
sensitivity_information psi 
)

generate an abstract heap location entity

Parameters
malloc_expis the argument expression of the call to malloc
psiis a pointer towards a structure which contains context and/or flow sensitivity information
Returns
an abstract heap location entity

free_type(ct)

Parameters
malloc_expalloc_exp
psisi

Definition at line 389 of file abstract_location.c.

391 {
393 
394  pips_debug(8, "begin for expression %s\n", expression_to_string(malloc_exp));
395  type t = malloc_arg_to_type(malloc_exp);
396  //type ct = copy_type(compute_basic_concrete_type(t));
397  //e = malloc_type_to_abstract_location(ct, psi);
399  free_type(t)/*, free_type(ct)*/;
400  pips_debug(8, "returning entity %s of type %s\n", entity_name(e),
402 
403  return e;
404 }
entity malloc_type_to_abstract_location(type t, sensitivity_information *psi)
generate an abstract heap location entity

References entity_name, entity_type, entity_undefined, expression_to_string(), free_type(), malloc_arg_to_type(), malloc_type_to_abstract_location(), pips_debug, and string_of_type().

Referenced by calloc_to_abstract_location(), flow_sensitive_malloc_to_points_to_sinks(), heap_intrinsic_to_post_pv(), and original_malloc_to_abstract_location().

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

◆ malloc_type_to_abstract_location()

entity malloc_type_to_abstract_location ( type  t,
sensitivity_information psi 
)

generate an abstract heap location entity

Parameters
tis type of the allocated space
psiis a pointer towards a structure which contains context and/or flow sensitivity information
Returns
an abstract heap location entity

in case we want an anywhere abstract heap location : the property ABSTRACT_HEAP_LOCATIONS is set to "unique" and a unique abstract location is used for all heap buckets.

in case the property ABSTRACT_HEAP_LOCATIONS is set to "insensitive": an abstract location is used for each function.

in case the property ABSTRACT_HEAP_LOCATIONS is set to "flow-sensitive" or "context-sensitive".

No difference here between the two values. The diffferent behavior will show when points-to and effects are translated at call sites

At this level, we want to use the statement number or the statement ordering. The statement ordering is safer because two statements or more can be put on the same line. The statement number is more user-friendly.

There is no need to distinguish between types since the statement ordering is at least as effective.

Parameters
psisi

Definition at line 324 of file abstract_location.c.

325 {
327  const char* opt = get_string_property("ABSTRACT_HEAP_LOCATIONS");
328  bool type_sensitive_p = !get_bool_property("ALIASING_ACROSS_TYPES");
329 
330  pips_debug(8, "begin for type %s\n",
331  string_of_type(t));
332  /* in case we want an anywhere abstract heap location : the property
333  ABSTRACT_HEAP_LOCATIONS is set to "unique" and a unique abstract
334  location is used for all heap buckets. */
335  if(strcmp(opt, "unique")==0){
336  if(type_sensitive_p)
338  else
340  }
341 
342  /* in case the property ABSTRACT_HEAP_LOCATIONS is set to
343  "insensitive": an abstract location is used for each function. */
344  else if(strcmp(opt, "insensitive")==0){
345  if(type_sensitive_p)
347  copy_type(t));
348  else
350  }
351 
352  /* in case the property ABSTRACT_HEAP_LOCATIONS is set to
353  "flow-sensitive" or "context-sensitive".
354 
355  No difference here between the two values. The diffferent
356  behavior will show when points-to and effects are translated at
357  call sites
358 
359  At this level, we want to use the statement number or the
360  statement ordering. The statement ordering is safer because two
361  statements or more can be put on the same line. The statement
362  number is more user-friendly.
363 
364  There is no need to distinguish between types since the statement
365  ordering is at least as effective.
366  */
367  else if(strcmp(opt, "flow-sensitive")==0
368  || strcmp(opt, "context-sensitive")==0 )
371  copy_type(t));
372  else
373  pips_user_error("Unrecognized value for property ABSTRACT_HEAP_LOCATION:"
374  " \"%s\"", opt);
375 
376  pips_debug(8, "returning entity %s of type %s\n", entity_name(e),
378 
379  return e;
380 }
entity entity_flow_or_context_sentitive_heap_location(int stmt_number, type t)
entity entity_all_module_heap_locations_typed(entity m, type t)
entity entity_all_heap_locations_typed(type t)
char * get_string_property(const char *)
#define pips_user_error
Definition: misc-local.h:147
#define statement_number(x)
Definition: ri.h:2452

References copy_type(), sensitivity_information::current_module, sensitivity_information::current_stmt, entity_all_heap_locations(), entity_all_heap_locations_typed(), entity_all_module_heap_locations(), entity_all_module_heap_locations_typed(), entity_flow_or_context_sentitive_heap_location(), entity_name, entity_type, entity_undefined, get_bool_property(), get_string_property(), pips_debug, pips_user_error, statement_number, and string_of_type().

Referenced by malloc_to_abstract_location().

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

◆ memory_dereferencing_p()

bool memory_dereferencing_p ( reference  r)

Does the set of locations referenced by r depend on a pointer dereferencing?

Let's hope that all Fortran 77 references will return false...

See effect_reference_dereferencing_p()

Get rid of simple Fortran-like array accesses

This is a simple array access

cycle with alias-classes library: import explictly

entity_heap_variable_p(v)

Heap modelization is behind

Let's walk the subscript list and see if the type associated to the nth subscript is a pointer type and if the (n+1)th subscript is a zero.

Since it is subscripted, there is dereferencing

No dereferencing

Definition at line 92 of file effects.c.

93 {
94  bool dereferencing_p = false;
96  type vt = entity_type(v);
98  list sl = reference_indices(r); // subscript list
99 
100  // FI: constant string such as "hello world" are used ni reference
101  // although they are 0-ary functions
102  if(! type_functional_p(vt)) {
103 
104  /* Get rid of simple Fortran-like array accesses */
106  /* This is a simple array access */
107  dereferencing_p = false;
108  }
109  else if(!ENDP(sl)) {
110  /* cycle with alias-classes library: import explictly */
113  pips_internal_error("Do we want to subscript abstract locations?");
114  }
115  else if(false /* entity_heap_variable_p(v)*/) {
116  /* Heap modelization is behind*/
117  }
118  else if(entity_variable_p(v)) {
119  /* Let's walk the subscript list and see if the type associated
120  * to the nth subscript is a pointer type and if the (n+1)th
121  * subscript is a zero.
122  */
123  list csl = sl; // current subscript list
124  type ct = uvt; // current type
125  if(pointer_type_p(uvt)) {
126  /* Since it is subscripted, there is dereferencing */
127  dereferencing_p = true;
128  csl = NIL;
129  }
130  else if(array_type_p(uvt)) {
131  variable v = type_variable(uvt);
132  int d = (int) gen_length(variable_dimensions(v));
133  int sn = (int) gen_length(sl);
134  if(sn<=d) {
135  dereferencing_p = false;
136  csl = NIL;
137  }
138  else {
139  ct = array_type_to_element_type(uvt);
140  int i;
141  for(i=1;i<=d;i++)
142  POP(csl);
143  }
144  }
145  else if(struct_type_p(uvt)) {
146  int sn = (int) gen_length(sl);
147  if(sn<=1) {
148  dereferencing_p = false;
149  csl = NIL;
150  }
151  else {
152  expression s = EXPRESSION(CAR(sl));
154  POP(csl);
155  }
156  }
157  else {
158  ; // FI: do nothing but acceleration possible with struct_type_p()
159  }
160  while(!dereferencing_p && !ENDP(csl)) {
161  expression se = EXPRESSION(CAR(csl));
163  if(pointer_type_p(ct) && !ENDP(CDR(csl))) {
164  dereferencing_p = true;
165  }
166  else if(array_type_p(ct)) {
167  int n = (int) array_type_dimension(ct);
168  for(int i = 0; i<n && !ENDP(csl); i++) {
169  POP(csl);
170  if(i>0) {
171  // Update ct
172  expression se = EXPRESSION(CAR(csl));
174  }
175  }
176  }
177  else {
178  POP(csl);
179  }
180  }
181  }
182  else {
183  pips_internal_error("Unexpected entity kind \"%s\"", entity_name(v));
184  }
185  }
186  else {
187  /* No dereferencing */
188  ;
189  }
190  }
191 
192  return dereferencing_p;
193 }
type points_to_expression_to_concrete_type(expression)
The type returned is stored in a hash-table.
Definition: type.c:617
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
type subscripted_type_to_type(type, expression)
Returns the type of an object of type t subscripted by expression se.
Definition: type.c:5562
unsigned int array_type_dimension(type)
Definition: type.c:2947
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
type array_type_to_element_type(type)
returns the type of the elements of an array type, as a newly allocated type.
Definition: type.c:5700

References array_type_dimension(), array_type_p(), array_type_to_element_type(), CAR, CDR, ENDP, entity_abstract_location_p(), entity_basic_concrete_type(), entity_name, entity_type, entity_variable_p, EXPRESSION, gen_length(), int, NIL, pips_internal_error, pointer_type_p(), points_to_expression_to_concrete_type(), POP, reference_indices, reference_variable, struct_type_p(), subscripted_type_to_type(), type_functional_p, type_variable, ultimate_type(), and variable_dimensions.

Referenced by consistent_points_to_arc_p().

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

◆ merge_points_to_cell_lists()

list merge_points_to_cell_lists ( list  l1,
list  l2 
)

Add in "l1" elements of "l2" that are not yet in "l1".

List "l2" is then destroyed.

This is a set union.

Parameters
l11
l22

Definition at line 134 of file points_to.c.

135 {
136  list lt = NIL;
137  FOREACH(CELL, c2, l2) {
138  if(!points_to_cell_in_list_p(c2, l1)) {
139  lt = CONS(CELL,c2, lt);
140  }
141  }
142  lt = gen_nreverse(lt);
143  l1 = gen_nconc(l1, lt);
144  gen_free_list(l2);
145  return l1;
146 }
bool points_to_cell_in_list_p(cell c, list L)
Definition: points_to.c:117

References CELL, CONS, FOREACH, gen_free_list(), gen_nconc(), gen_nreverse(), NIL, and points_to_cell_in_list_p().

Referenced by dereferencing_to_sinks().

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

◆ module_to_analyzed_array_locations()

list module_to_analyzed_array_locations ( entity  m)

m is supposed to be a module entity

Definition at line 393 of file locations.c.

394 {
395  list ll = NIL;
396  value v = entity_initial(m);
397  code c = value_code(v);
398  list dl = code_declarations(c);
399 
400  FOREACH(ENTITY, e, dl) {
402  ll = CONS(ENTITY, e, ll);
403  }
404  return ll;
405 }
bool array_location_entity_of_module_p(entity le, entity m)
Expanded version of location_entity_of_module_p()
Definition: locations.c:374

References array_location_entity_of_module_p(), code_declarations, CONS, ENTITY, entity_initial, FOREACH, NIL, and value_code.

Referenced by apply_array_effect_to_transformer().

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

◆ nowhere_cell_p()

bool nowhere_cell_p ( cell  c)

Target of an undefined pointer.

Definition at line 455 of file effects.c.

456 {
457  bool nowhere_p;
459  entity v = reference_variable(r);
460 
461  nowhere_p = entity_typed_nowhere_locations_p(v);
462 
463  return nowhere_p;
464 }

References cell_any_reference(), entity_typed_nowhere_locations_p(), and reference_variable.

Referenced by atomic_points_to_cell_p(), binary_intrinsic_call_to_points_to_sinks(), cell_must_point_to_nowhere_sink_in_set_p(), cell_points_to_non_null_sink_in_set_p(), cell_points_to_nowhere_sink_in_set_p(), cells_may_not_point_to_null_p(), cells_to_read_or_write_effects(), check_type_of_points_to_cells(), compute_points_to_gen_set(), dereferencing_to_sinks(), equal_condition_to_points_to(), extended_source_to_sinks(), filter_formal_context_according_to_actual_context(), filter_formal_out_context_according_to_formal_in_context(), freed_list_to_points_to(), fuse_points_to_sink_cells(), generic_points_to_source_to_sinks(), generic_reference_to_points_to_matching_list(), internal_pointer_assignment_to_points_to(), intrinsic_call_to_points_to(), list_assignment_to_points_to(), merge_actual_and_formal_sinks(), new_filter_formal_context_according_to_actual_context(), new_recursive_filter_formal_context_according_to_actual_context_for_pointer_pair(), non_equal_condition_to_points_to(), offset_cell(), offset_points_to_cell(), pointer_arithmetic_to_points_to(), points_to_binding_arguments(), points_to_cell_types_compatibility(), points_to_function_projection(), points_to_reference_to_translation(), points_to_source_cell_compatible_p(), points_to_source_to_translations(), points_to_with_stripped_sink(), print_or_dump_points_to(), process_casted_sinks(), process_casted_sources(), recursive_filter_formal_context_according_to_actual_context(), reference_dereferencing_to_points_to(), reference_to_points_to_translations(), remove_impossible_arcs_to_null(), source_to_sinks(), subscript_to_points_to_sinks(), and words_points_to().

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

◆ null_cell_p()

bool null_cell_p ( cell  c)

Definition at line 466 of file effects.c.

467 {
468  bool null_p;
470  entity v = reference_variable(r);
471 
472  null_p = entity_null_locations_p(v);
473 
474  return null_p;
475 }

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

Referenced by atomic_points_to_cell_p(), binary_intrinsic_call_to_points_to_sinks(), cell_must_point_to_nowhere_sink_in_set_p(), cell_points_to_non_null_sink_in_set_p(), cell_points_to_nowhere_sink_in_set_p(), cell_points_to_null_sink_in_set_p(), cells_may_not_point_to_null_p(), cells_must_point_to_null_p(), cells_to_read_or_write_effects(), check_type_of_points_to_cells(), compute_points_to_gen_set(), dereferencing_subscript_to_points_to(), dereferencing_to_sinks(), expression_to_points_to_cells(), expression_to_points_to_sources(), extended_source_to_sinks(), filter_formal_context_according_to_actual_context(), freed_list_to_points_to(), freed_pointer_to_points_to(), fuse_points_to_sink_cells(), generic_atomic_points_to_cell_p(), generic_points_to_source_to_sinks(), generic_reference_to_points_to_matching_list(), list_assignment_to_points_to(), merge_actual_and_formal_sinks(), new_filter_formal_context_according_to_actual_context(), new_recursive_filter_formal_context_according_to_actual_context(), null_equal_condition_to_points_to(), null_non_equal_condition_to_points_to(), offset_cell(), offset_cells(), offset_points_to_cell(), pointer_arithmetic_to_points_to(), points_to_binding_arguments(), points_to_cell_types_compatibility(), points_to_reference_to_translation(), points_to_source_cell_compatible_p(), points_to_source_to_translations(), points_to_with_stripped_sink(), print_or_dump_points_to(), process_casted_sinks(), process_casted_sources(), recursive_filter_formal_context_according_to_actual_context(), reduce_cells_to_pointer_type(), reference_dereferencing_to_points_to(), reference_may_points_to_null_p(), reference_must_points_to_null_p(), reference_to_points_to_translations(), remove_impossible_arcs_to_null(), source_to_sinks(), and subscript_to_points_to_sinks().

+ Here is the call graph for this function:

◆ null_pointer_value_cell_p()

bool null_pointer_value_cell_p ( cell  c)

◆ null_pointer_value_entity()

entity null_pointer_value_entity ( void  )

Definition at line 87 of file pointer_values.c.

88 {
89  return entity_null_locations();
90 }

References entity_null_locations().

Referenced by declaration_to_post_pv(), make_null_pointer_value_cell(), and pointer_expression_to_transformer().

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

◆ null_pointer_value_entity_p()

bool null_pointer_value_entity_p ( entity  e)

◆ original_malloc_to_abstract_location()

reference original_malloc_to_abstract_location ( expression  ,
type  ,
type  ,
expression  ,
entity  ,
statement   
)

◆ pips_region_user_name()

const char* pips_region_user_name ( entity  ent)

char * pips_region_user_name(entity ent) output : the name of entity.

modifies : nothing. comment : allows to "catch" the PHIs entities, else, it works like pips_user_value_name() (see semantics.c).

external_value_name cannot be used because there is no need for the #new suffix, but the #old one is necessary

take care of the constant term TCST

ent is a PHI entity from the regions module

if (!hash_entity_to_values_undefined_p() && !entity_has_values_p(ent))

name = external_value_name(ent);

else

Parameters
entnt

Definition at line 169 of file prettyprint.c.

170 {
171  /* external_value_name cannot be used because there is no need for
172  the #new suffix, but the #old one is necessary */
173  const char* name;
174  if(ent == NULL)
175  /* take care of the constant term TCST */
176  name = "";
177  else {
178  char *ent_name = entity_name(ent);
179 
180  if (strncmp(ent_name, REGIONS_MODULE_NAME, 7) == 0)
181  /* ent is a PHI entity from the regions module */
182  name = entity_local_name(ent);
183  else
184  {
185  /* if (!hash_entity_to_values_undefined_p() && !entity_has_values_p(ent)) */
186 /* name = external_value_name(ent); */
187 /* else */
188  name = entity_minimal_name(ent);
189  }
190  }
191 
192  return name;
193 }

References entity_local_name(), entity_minimal_name(), entity_name, and REGIONS_MODULE_NAME.

Referenced by copy_write_statement_with_cumulated_regions(), reg_sc_debug(), reg_v_debug(), text_pointer_value(), text_points_to_relation(), and text_region_no_action().

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

◆ pointer_value_compare()

int pointer_value_compare ( cell_relation ppv1,
cell_relation ppv2 
)

Compares two pointer values for sorting.

The first criterion is based on names. Local entities come first; then they are sorted according to the lexicographic order of the module name, and inside each module name class, according to the local name lexicographic order. Then for a given entity name, a read effect comes before a write effect. It is assumed that there is only one effect of each type per entity. bc.

result

compare first references of *ppv1 and *ppv2

same first cells

put second cells value_of before address_of

both are value_of or address_of

compare second cells

Parameters
ppv1pv1
ppv2pv2

Definition at line 255 of file compare.c.

256 {
257  int ppv1_pos = 0; /* result */
258  /* compare first references of *ppv1 and *ppv2 */
259 
260  cell ppv1_first_c = cell_relation_first_cell(*ppv1);
261  cell ppv2_first_c = cell_relation_first_cell(*ppv2);
262 
263  pips_assert("there should not be preference cells in pointer values (ppv1 first) \n",
264  !cell_preference_p(ppv1_first_c));
265  pips_assert("there should not be preference cells in pointer values (ppv2 first) \n",
266  !cell_preference_p(ppv2_first_c));
267 
268  pips_assert("the first cell must have value_of interpretation (ppv1)\n",
270  pips_assert("the first cell must have value_of interpretation (ppv2)\n",
272 
273  ppv1_pos = cell_compare(&ppv1_first_c, &ppv2_first_c);
274 
275  if (ppv1_pos == 0) /* same first cells */
276  {
277  /* put second cells value_of before address_of */
278  bool ppv1_second_value_of_p = cell_relation_second_value_of_p(*ppv1);
279  bool ppv2_second_value_of_p = cell_relation_second_value_of_p(*ppv2);
280 
281  ppv1_pos = (ppv1_second_value_of_p == ppv2_second_value_of_p) ? 0 :
282  (ppv1_second_value_of_p ? -1 : 1);
283 
284  if (ppv1_pos == 0) /* both are value_of or address_of*/
285  {
286  /* compare second cells */
287  cell ppv1_second_c = cell_relation_second_cell(*ppv1);
288  cell ppv2_second_c = cell_relation_second_cell(*ppv2);
289  ppv1_pos = cell_compare(&ppv1_second_c, &ppv2_second_c);
290 
291  }
292  }
293  return(ppv1_pos);
294 }
#define cell_relation_second_cell(cr)
#define cell_relation_second_value_of_p(cr)
#define cell_relation_first_cell(cr)
#define cell_relation_first_value_of_p(cr)

References cell_compare(), cell_preference_p, cell_relation_first_cell, cell_relation_first_value_of_p, cell_relation_second_cell, cell_relation_second_value_of_p, and pips_assert.

Referenced by simple_pvs_syntactically_equal_p(), and text_pointer_values().

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

◆ points_to_array_reference_p()

bool points_to_array_reference_p ( reference  r)

Is this a reference to an array or a reference to a pointer? This is not linked to the type of the reference, as a reference may be a pointer, such as "a[10]" when "a" is declared int "a[10][20]".

Look for the last field among the subscript

Definition at line 599 of file points_to.c.

600 {
601  bool array_p = false;
602  list sl = reference_indices(r);
603  entity v = reference_variable(r);
604 
605  if(ENDP(sl)) {
607  array_p = array_type_p(t);
608  }
609  else {
610  /* Look for the last field among the subscript */
611  list rsl = gen_nreverse(sl);
612  type t = type_undefined;
613  int i = 0;
614  FOREACH(EXPRESSION, se, rsl) {
618  break;
619  }
620  i++;
621  }
622  if(type_undefined_p(t)) {
624  variable vt = type_variable(t);
625  list dl = variable_dimensions(vt);
626  int d = (int) gen_length(dl);
627  int i = (int) gen_length(rsl);
628  if(i<d)
629  array_p = true;
630  }
631  else {
632  if(i==0) { // FI: could be merged with the "else if" clause
633  array_p = array_type_p(t);
634  }
635  else if(array_type_p(t)) {
636  variable vt = type_variable(t);
637  list dl = variable_dimensions(vt);
638  int d = (int) gen_length(dl);
639  if(i<d)
640  array_p = true;
641  }
642  }
644  }
645  return array_p;
646 }
bool field_reference_expression_p(expression e)
Check if expression "e" is a reference to a struct field.
Definition: points_to.c:224

References array_type_p(), ENDP, entity_basic_concrete_type(), EXPRESSION, expression_reference(), f(), field_reference_expression_p(), FOREACH, gen_length(), gen_nreverse(), int, reference_indices, reference_variable, type_undefined, type_undefined_p, type_variable, and variable_dimensions.

Referenced by points_to_cell_add_fixed_subscripts(), and subscript_to_points_to_sinks().

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

◆ points_to_array_reference_to_type()

type points_to_array_reference_to_type ( reference  r)

If this is an array reference, what is the type of the underlying array type?

This information cannot be obtained by direct type information because subarrays are typed as pointers to even smaller arrays.

If it is not an array reference, the returned type is undefined.

No new type is allocated.

Look for the last field among the subscript

Definition at line 657 of file points_to.c.

658 {
659  list sl = reference_indices(r);
660  entity v = reference_variable(r);
661  type t = type_undefined;
662 
663  if(ENDP(sl)) {
665  }
666  else {
667  /* Look for the last field among the subscript */
668  list rsl = gen_nreverse(sl);
669  FOREACH(EXPRESSION, se, rsl) {
673  break;
674  }
675  }
676  if(type_undefined_p(t)) {
678  }
679  else {
680  ;
681  }
683  }
684  return t;
685 }

References ENDP, entity_basic_concrete_type(), EXPRESSION, expression_reference(), f(), field_reference_expression_p(), FOREACH, gen_nreverse(), reference_indices, reference_variable, type_undefined, and type_undefined_p.

Referenced by points_to_cell_add_fixed_subscripts().

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

◆ points_to_cell_add_field_dimension()

cell points_to_cell_add_field_dimension ( cell  c,
entity  f 
)

Functions about points-to cells - There is no cell.c file.

add a field to a cell if it is meaningful

FI: should we also add the necessary zero subscripts when the field is an array?

Definition at line 1444 of file effects.c.

1445 {
1446  if(cell_reference_p(c)) {
1447  reference r = cell_reference(c);
1449  }
1450  else if(cell_preference_p(c)) {
1451  preference pr = cell_preference(c);
1454  }
1455  else if(cell_gap_p(c))
1456  pips_internal_error("Not applicable on gaps.\n");
1457  else
1458  pips_internal_error("Unknown kind of cell.\n");
1459  return c;
1460 }
reference reference_add_field_dimension(reference r, entity f)
add a field f as a subscript to a reference r if it is meaningful.
Definition: effects.c:1475

References cell_gap_p, cell_preference, cell_preference_p, cell_reference, cell_reference_p, f(), pips_internal_error, preference_reference, and reference_add_field_dimension().

Referenced by any_source_to_sinks(), anywhere_source_to_sinks(), binary_intrinsic_call_to_points_to_sinks(), generic_points_to_cell_to_useful_pointer_cells(), new_recursive_filter_formal_context_according_to_actual_context(), points_to_translation_of_struct_formal_parameter(), and recursive_cell_to_pointer_cells().

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

◆ points_to_cell_add_fixed_subscripts()

void points_to_cell_add_fixed_subscripts ( cell  c,
bool  zero_p 
)

Convert a reference to an array into a reference to its first element.

Note: is this unconditional? Do you add the right number of subscripts according to the type?

Parameters
zero_pero_p

Definition at line 1594 of file effects.c.

1595 {
1596  bool to_be_freed = false;
1597  type t = type_undefined;
1600  //type at = points_to_array_reference_to_type(r);
1601  //t = array_type_to_element_type(at);
1603  // partial memory leak with "at"?
1604  }
1605  else
1606  t = points_to_cell_to_type(c, &to_be_freed);
1607 
1608  if(zero_p)
1610  else
1612  if(to_be_freed) free_type(t);
1613 }
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 points_to_array_reference_p(reference)
Is this a reference to an array or a reference to a pointer? This is not linked to the type of the re...
Definition: points_to.c:599
type points_to_array_reference_to_type(reference)
If this is an array reference, what is the type of the underlying array type?
Definition: points_to.c:657
void reference_add_zero_subscripts(reference r, type t)
Definition: expression.c:261
void reference_add_unbounded_subscripts(reference r, type t)
Definition: expression.c:300

References cell_any_reference(), free_type(), points_to_array_reference_p(), points_to_array_reference_to_type(), points_to_cell_to_type(), reference_add_unbounded_subscripts(), reference_add_zero_subscripts(), and type_undefined.

Referenced by points_to_cell_add_unbounded_subscripts(), and points_to_cell_add_zero_subscripts().

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

◆ points_to_cell_add_unbounded_subscripts()

void points_to_cell_add_unbounded_subscripts ( cell  c)

Definition at line 1632 of file effects.c.

1633 {
1635 }
void points_to_cell_add_fixed_subscripts(cell c, bool zero_p)
Convert a reference to an array into a reference to its first element.
Definition: effects.c:1594

References points_to_cell_add_fixed_subscripts().

Referenced by any_source_to_sinks(), assignment_to_points_to(), generic_points_to_cell_to_useful_pointer_cells(), generic_stub_source_to_sinks(), internal_pointer_assignment_to_points_to(), new_recursive_filter_formal_context_according_to_actual_context(), points_to_translation_of_struct_formal_parameter(), recursive_cell_to_pointer_cells(), and variable_to_pointer_locations().

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

◆ points_to_cell_add_zero_subscript()

void points_to_cell_add_zero_subscript ( cell  c)

Definition at line 1620 of file effects.c.

1621 {
1624 }
void reference_add_zero_subscript(reference r)
No check on reference r.
Definition: expression.c:267

References cell_any_reference(), and reference_add_zero_subscript().

Referenced by filter_formal_context_according_to_actual_context(), new_filter_formal_context_according_to_actual_context(), points_to_translation_of_formal_parameters(), and recursive_filter_formal_context_according_to_actual_context().

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

◆ points_to_cell_add_zero_subscripts()

void points_to_cell_add_zero_subscripts ( cell  c)

Definition at line 1615 of file effects.c.

1616 {
1618 }

References points_to_cell_add_fixed_subscripts().

Referenced by binary_intrinsic_call_to_points_to_sinks(), generic_stub_source_to_sinks(), internal_pointer_assignment_to_points_to(), points_to_cell_types_compatibility(), and reference_to_points_to_sinks().

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

◆ points_to_cell_complete_with_zero_subscripts()

void points_to_cell_complete_with_zero_subscripts ( cell  c)

Definition at line 1626 of file effects.c.

1627 {
1630 }
void reference_complete_with_zero_subscripts(reference r)
Reference r to an array maybe partial, as is possible in C: with declaration "int a[10][10]",...
Definition: expression.c:278

References cell_any_reference(), and reference_complete_with_zero_subscripts().

Referenced by filter_formal_context_according_to_actual_context(), and new_filter_formal_context_according_to_actual_context().

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

◆ points_to_cell_equal_p()

◆ points_to_cell_in_list_p()

bool points_to_cell_in_list_p ( cell  c,
list  L 
)

◆ points_to_cell_to_concrete_type()

type points_to_cell_to_concrete_type ( cell  c)

◆ points_to_cell_to_type()

◆ points_to_cell_to_upper_bound_points_to_cells()

list points_to_cell_to_upper_bound_points_to_cells ( cell  c)

Return a list of cells that are larger than cell "c" in the points-to cell lattice.

This goal is quite open because a[1][2] is dominated by both a[*][2] and a[1][*], then by a[*][*]. Assuming "a" is variable of function "foo", then we have "foo:*STACK*_b0", "*ANYMODULE*:*STACK*_b0", "foo:*ANYWHERE*_b0", "*ANYMODULE*:*ANYWHERE*_b0", "*ANYMODULE*:*ANYWHERE*".

They would all be useful to guarantee the consistency of the points-to information wrt the points-to cell lattice, but we'd rather maintain a partially consistent points-to graph and rely on functions using it to add the necessary points-to arcs.

A lattice-consistent points-to graph would contain too many arcs as x->y implies x'->y' for all x' bigger than x and y' bigger then y...

For the time being, we only need to convert a[i][j][k] into a[*][*][*] when i, j and k are real subscript expressions, not fields.

We return an empty list when cell "c" does not need any upper bound, as is the case with a, a[f] where f is a field, a[*] and all the abstract locations.

So, for the time being, this function returns a list with one or zero elements.

Definition at line 973 of file points_to.c.

974 {
975  list ubl = NIL; // upper bound list
977  entity v = reference_variable(r);
979  list sel = reference_indices(r); // subscript expression list
980  list nsel = NIL; // new subscript expression list
981  bool new_cell_p = false;
982  FOREACH(EXPRESSION, se, sel) {
984  if(integer_expression_p(se)) {
986  new_cell_p = true;
987  }
988  else
989  nse = copy_expression(se);
990  nsel = CONS(EXPRESSION, nse, nsel);
991  }
992  if(new_cell_p) {
993  nsel = gen_nreverse(nsel);
994  reference nr = make_reference(v, nsel);
995  cell nc = make_cell_reference(nr);
996  ubl = CONS(CELL, nc, ubl);
997  }
998  else
999  gen_full_free_list(nsel);
1000  }
1001  return ubl;
1002 }
void gen_full_free_list(list l)
Definition: genClib.c:1023
bool integer_expression_p(expression e)
Definition: expression.c:601

References CELL, cell_any_reference(), CONS, copy_expression(), entity_abstract_location_p(), EXPRESSION, expression_undefined, FOREACH, gen_full_free_list(), gen_nreverse(), integer_expression_p(), make_cell_reference(), make_reference(), make_unbounded_expression(), NIL, reference_indices, and reference_variable.

Referenced by points_to_cells_to_upper_bound_points_to_cells().

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

◆ points_to_cell_types_compatibility()

void points_to_cell_types_compatibility ( cell  l,
cell  r 
)

Make sure that cell l can points towards cell r.

FI-AM/FC: Unfortunately, a lot of specification work is missing to develop this function while taking care of abstract locations and their lattice.

  1. Restrictions on cell "l"

    1.1 "l" cannot be the abstract nowhere/undefined cell

...

Note: this should be part of points_to_set_consistent_p(), which is called consistent_points_to_set(), but this function goes beyond checking the compatibility. It enforces it when legal and possible.

Maybe this function should be relocated in alias-classes

Beware of possible side-effects on l

FI, 10 August 2012: this function is a mess. No side effect should be applied. it should be redesigned to check compatibility cases one after the other and it should be renamed points_to_cell_types_compatibility_p()

FI, 14 August 2012: the dimension of the sink entity and sink reference must be greater than the dimension of the source reference. This is not checked yet.

FI, 19 August 2012: all cells used in a points-to arc must be scalar, either pointers or basic types

&& overloaded_type_p(urt)

The source points towards an array and the cell is an element of this array.

Formal parameters and potentially stubs can be assumed to points towards an array although they are declared as pointers to a scalar.

This should never be a problem when sink cells are always array elements and not arrays.

Here we may be in trouble because of the heap modeling malloc() returns by default a "void *", or sometimes a "char *" which may be casted into anything...

The dimension of the allocated array should be given by the size of the pointed type and by the size of the right type.

Also, we have different heap modelling, with different flexibilities

& !all_heap_locations_typed_cell_p(r)

all_heap_locations_typed_cell_p(r)

There must be a typing issue.

This may happen with the heap model

Is it an (implicit) array of pointers

This may happen with the heap model

Definition at line 985 of file type.c.

986 {
988  if(null_cell_p(r))
989  ;
991  // FI: I'm not sure enought filtering has been performed... to
992  // have here type information, especially with an anywhere or a
993  // nowhere/undefined not typed
994 
995  // FI : tests supplementaires pour eviter les cells qui ne sont pas typees:-(
996 
997  bool l_to_be_freed, r_to_be_freed;
998  type lt = points_to_cell_to_type(l, &l_to_be_freed);
999  type rt = points_to_cell_to_type(r, &r_to_be_freed);
1002  if(C_pointer_type_p(ult)) {
1003  type pt = pointer_type_p(ult) ?
1006 
1007  // Several options are possible
1008 
1009  bool get_bool_property(const char *);
1010  if(array_pointer_type_equal_p(pt, urt))
1011  ; // the pointed type is the type of the right cell
1012  // FI: we could/should add a compatibility type between void
1013  // and any scalar type
1014  // The problem occurs in Pointers/fulguro13 because a cast is
1015  // not processed:
1016  // fgUINT16 *array_s = (fgUINT16 *) vct->array;
1017  // FI->AM/FC/PJ: we need a trick to handle the casts or the
1018  // typing of the points-to graph is not possible
1019  else if(scalar_type_p(pt) && type_void_p(urt)) {
1020  // A void * pointer may be assigned to anything?
1021  ; // OK, they are compatible...
1022  }
1023  else if(type_void_p(pt) /* && overloaded_type_p(urt)*/ ) {
1024  // a void * is expected to point toward any type, which is
1025  // encoded with overloaded but could be anything when casts
1026  // or functions, user or intrinsic, are used. See fulguro03.c
1027  ;
1028  }
1029  else if(overloaded_type_p(urt)) {
1030  // This is compatible with any pointed type pt by definition
1031  // of overloaded. See fulguro03.c
1032  ;
1033  }
1034  else if(array_type_p(pt) && scalar_type_p(urt)) {
1035  /* The source points towards an array and the cell is an
1036  element of this array. */
1038  basic rb = variable_basic(type_variable(urt));
1039  if(basic_equal_p(pb, rb)) {
1040  ; // OK
1041  }
1042  else {
1043  pips_internal_error("???");
1044  }
1045  }
1046  else if(array_type_p(urt)
1047  && !get_bool_property("POINTS_TO_STRICT_POINTER_TYPES")) {
1048  /* Formal parameters and potentially stubs can be assumed to
1049  * points towards an array although they are declared as
1050  * pointers to a scalar.
1051  *
1052  * This should never be a problem when sink cells are always
1053  * array elements and not arrays.
1054  */
1055  if(type_variable_p(pt)) {
1057  basic rb = variable_basic(type_variable(urt));
1058  if(basic_equal_p(pb,rb)) {
1059  ; // OK, they are compatible
1060  }
1061  else {
1062  fprintf(stderr, "Type pointed by source \"pt\": \"");
1063  print_type(pt);
1064  fprintf(stderr, "\"\nSink type \"urt\": \"");
1065  print_type(urt);
1066  pips_internal_error("\"\nIncompatible basics.\n");
1067  }
1068  }
1069  else {
1070  fprintf(stderr, "Pointed type \"pt\": ");
1071  print_type(pt);
1072  pips_internal_error("Unexpected type \"pt\".\n");
1073  }
1074  }
1075  else if(array_type_p(urt)
1076  && get_bool_property("POINTS_TO_STRICT_POINTER_TYPES")) {
1077  // Pointers/assignment10.c
1078  if(type_variable_p(pt)) {
1080  basic rb = variable_basic(type_variable(urt));
1081  if(basic_equal_p(pb,rb)) {
1082  // OK, they are compatible, but r must be subscripted
1084  }
1085  else {
1086  fprintf(stderr, "Type pointed by source \"pt\": \"");
1087  print_type(pt);
1088  fprintf(stderr, "\"\nSink type \"urt\": \"");
1089  print_type(urt);
1090  pips_internal_error("\"\nIncompatible basics.\n");
1091  }
1092  }
1093  }
1094  else if(type_functional_p(urt)) {
1095  // FI->AM: we should check that the function is a constant
1096  // with no parameters
1097  type ret_t = functional_result(type_functional(urt));
1098  type u_ret_t = compute_basic_concrete_type(ret_t);
1099  if(pointer_type_p(u_ret_t)) {
1100  pips_internal_error("This should be useless.\n");
1101  // FI->AM: must be useless... Designed for C constant strings, but...
1102  type p_u_ret_t = type_to_pointed_type(u_ret_t);
1103  if(array_pointer_type_equal_p(pt, p_u_ret_t))
1104  ;
1105  else
1106  pips_internal_error("Type mismatch.\n");
1107  free_type(u_ret_t);
1108  }
1109  else if(string_type_p(u_ret_t)) {
1110  // FI: hidden pointer...
1111  // char * fmt; ftm = "foo";
1112  variable ptv = type_variable(pt);
1113  basic ptb = variable_basic(ptv);
1114  if(basic_int_p(ptb) && basic_int(ptb)==1)
1115  ; // char
1116  else
1117  pips_internal_error("Illegal string assignment...\n");
1118  }
1119  else {
1120  pips_internal_error("Illegal assignment to pointer...\n");
1121  }
1122  }
1123  else {
1124  /* Here we may be in trouble because of the heap modeling
1125  * malloc() returns by default a "void *", or sometimes a
1126  * "char *" which may be casted into anything...
1127  *
1128  * The dimension of the allocated array should be given by
1129  * the size of the pointed type and by the size of the right
1130  * type.
1131  *
1132  * Also, we have different heap modelling, with different flexibilities
1133  */
1135  /*&& !all_heap_locations_typed_cell_p(r) */) {
1136  pips_internal_error("Type mistake for heap allocation. Probably a user error. It should have been trapped at a higher level.\n");
1137  type nt = copy_type(pt);
1138  if(array_type_p(nt)
1139  || get_bool_property("POINTS_TO_STRICT_POINTER_TYPES"))
1140  ; // Do not add a dimension to an existing array.
1141  else if(!type_void_p(nt)) {
1142  variable v = type_variable(nt);
1144  // FI FI FI: should be computed... and checked
1146  dimension d = make_dimension(z, s, NIL);
1148  }
1149  // FI: could be a function entity_type_substitution()...
1150  // but interference with r_to_be_freed
1151  r_to_be_freed = true;
1152  reference rr = cell_any_reference(r);
1153  entity rv = reference_variable(rr);
1154  // This assignment breaks the internal consistency of heap modelling
1156  pips_internal_error("Incompatible types for \"%s\".\n",
1157  entity_name(rv));
1158  entity_type(rv) = nt;
1159  }
1160  else if(all_heap_locations_cell_p(r))
1161  ; // always compatible
1162  else if(false /* all_heap_locations_typed_cell_p(r)*/)
1163  ; // FI: I am not sure what to do...
1164  else if(null_cell_p(r)) {
1165  ; // always compatible
1166  }
1167  else if(anywhere_cell_p(r)) {
1168  ; // not typed anywhere, always compatible
1169  }
1170  else if(nowhere_cell_p(r)) {
1171  ; // not typed nowhere/undefined, always compatible
1172  }
1173  else {
1174  /* There must be a typing issue. */
1175  fprintf(stderr, "Type pointed by source cell, \"pt\": \"");
1176  void print_points_to_cell(cell); // FI: library organization
1178  fprintf(stderr, "\" with type: \"");
1179  print_type(pt);
1180  fprintf(stderr, "\"\nType of sink cell, \"urt\": \"");
1182  fprintf(stderr, "\" with type: \"");
1183  print_type(urt);
1184  fprintf(stderr, "\"\n");
1185  pips_internal_error("Incompatible Types.\n");
1186  }
1187  }
1188  }
1189  else if(array_type_p(ult)) {
1190  /* This may happen with the heap model */
1191  extern bool get_bool_property(const char *);
1192  if(!get_bool_property("POINTS_TO_STRICT_POINTER_TYPES")) {
1193  /* Is it an (implicit) array of pointers*/
1194  basic ultb = variable_basic(type_variable(ult));
1195  if(basic_pointer_p(ultb)) { // Array
1196  // FI: "pt" should be freed later...
1197  // FI: should have been done earlier when building l
1198  // reference lr = cell_any_reference(l);
1199  // reference_add_zero_subscripts(lr, ult);
1202  // FI: subscripts must be added to the source reference lr
1203  // FI: implicit typing of pointers as array of pointers
1204  reference lr = cell_any_reference(l);
1206  }
1207  else {
1208  // FI: error message could be improved...
1209  pips_internal_error("Incompatible types.\n");
1210  }
1211  }
1212  else
1213  pips_internal_error("Not an array of pointers.\n");
1214  }
1215  else
1216  pips_internal_error("The source is an array but not a pointer.\n");
1217  }
1218  else if(overloaded_type_p(ult)) {
1219  /* This may happen with the heap model */
1220  ; // A pointer type is assumed
1221  }
1222  else {
1223  // Could be checked by points_to_source_cell_compatible_p()
1224  pips_internal_error("The source is not a pointer.\n");
1225  }
1226 
1227  if(l_to_be_freed) free_type(lt);
1228  if(r_to_be_freed) free_type(rt);
1229  free_type(ult), free_type(urt);
1230  }
1231  }
1232  return;
1233 }
bool points_to_sink_cell_compatible_p(cell c __attribute__((unused)))
Definition: type.c:1258
bool points_to_source_cell_compatible_p(cell c)
Definition: type.c:1241
bool anywhere_cell_p(cell)
Is it an anywhere cell?
Definition: effects.c:367
bool all_heap_locations_cell_p(cell)
Definition: effects.c:432
void points_to_cell_add_zero_subscripts(cell)
Definition: effects.c:1615
bool heap_cell_p(cell)
Any heap cell, more or less abstract or typed.
Definition: effects.c:420
#define print_points_to_cell(x)
Definition: print.c:377
void print_type(type t)
For debugging.
Definition: type.c:111
bool array_type_p(type t)
Definition: type.c:2942
bool type_equal_up_to_typedefs_and_qualifiers_p(type t1, type t2)
Definition: type.c:557
bool string_type_p(type t)
Definition: type.c:2854
type type_to_pointed_type(type t)
returns t if t is not a pointer type, and the pointed type if t is a pointer type.
Definition: type.c:5265
type array_type_to_element_type(type t)
returns the type of the elements of an array type, as a newly allocated type.
Definition: type.c:5700
bool pointer_type_p(type t)
Check for scalar pointers.
Definition: type.c:2993
bool scalar_type_p(type t)
Definition: type.c:2955
bool overloaded_type_p(type t)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
bool C_pointer_type_p(type t)
Returns OK for "char[]" as well as for "char *".
Definition: type.c:3011
#define functional_result(x)
Definition: ri.h:1444
#define basic_int_p(x)
Definition: ri.h:614
#define basic_int(x)
Definition: ri.h:616
#define type_functional(x)
Definition: ri.h:2952

References all_heap_locations_cell_p(), anywhere_cell_p(), array_pointer_type_equal_p(), array_type_p(), array_type_to_element_type(), basic_equal_p(), basic_int, basic_int_p, basic_pointer, basic_pointer_p, C_pointer_type_p(), cell_any_reference(), compute_basic_concrete_type(), CONS, copy_type(), DIMENSION, entity_name, entity_type, fprintf(), free_type(), functional_result, get_bool_property(), heap_cell_p(), int_to_expression(), make_dimension(), make_unbounded_expression(), NIL, nowhere_cell_p(), null_cell_p(), overloaded_type_p(), pips_internal_error, pointer_type_p(), points_to_cell_add_zero_subscripts(), points_to_cell_to_type(), points_to_sink_cell_compatible_p(), points_to_source_cell_compatible_p(), print_points_to_cell, print_type(), reference_add_zero_subscripts(), reference_variable, scalar_type_p(), string_type_p(), type_equal_up_to_typedefs_and_qualifiers_p(), type_functional, type_functional_p, type_to_pointed_type(), type_variable, type_variable_p, type_void_p, variable_basic, and variable_dimensions.

Referenced by create_stub_points_to(), and gen_may_constant_paths().

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

◆ points_to_cell_update_last_subscript()

void points_to_cell_update_last_subscript ( cell  c,
expression  s 
)

Transform reference a[i]...[j] and expression s into reference a[i]..[j+s] if j and s are constant integer expressions, and into reference a[i]..[*] otherwise.

Cell c is updated by side effect.

This has been implemented in several places...

Definition at line 1643 of file effects.c.

1644 {
1646  list sl = reference_indices(r);
1647  if(ENDP(sl)) {
1648  // FI: we could do something special for heap abstract locations...
1649  // entity v = reference_variable(r);
1650  pips_internal_error("Wrong argument c.\n");
1651  }
1652  else {
1653  list lsl = gen_last(sl);
1654  expression is = EXPRESSION(CAR(lsl));
1655  intptr_t c1, c2;
1657  if(expression_integer_value(is, &c1) && expression_integer_value(s, &c2)) {
1658  ns = int_to_expression((int) c1+c2);
1659  }
1660  else {
1662  }
1663  EXPRESSION_(CAR(lsl)) = ns;
1664  }
1665 }

References CAR, cell_any_reference(), ENDP, EXPRESSION, EXPRESSION_, expression_integer_value(), expression_undefined, gen_last(), int_to_expression(), intptr_t, make_unbounded_expression(), pips_internal_error, and reference_indices.

Referenced by subscripted_reference_to_points_to().

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

◆ points_to_cells_intersect_p()

bool points_to_cells_intersect_p ( cell  lc,
cell  rc 
)

points-to cells use abstract addresses, hence the proper comparison is an intersection.

simple references are considered to be singleton.

Assume no aliasing between variables and within data structures.

It is safe to assume intersection...

Parameters
lcc
rcc

Definition at line 532 of file points_to.c.

533 {
534  bool intersect_p = false;
535  if(cell_equal_p(lc, rc)) {
536  // FI: too simple... All the subscript should be checked.
537  // unbounded expressions should be used to decide about a possible
538  // intersection... Unless this is guarded by
539  // atomic_points_to_reference_p(). To be investigated.
540  intersect_p = true;
541  }
542  else {
543  // Look for abstract domains
544  // Probably pretty complex...
545  // Simple first version...
546  reference lr = cell_any_reference(lc);
547  entity le = reference_variable(lr);
548  reference rr = cell_any_reference(rc);
549  entity re = reference_variable(rr);
550  intersect_p = entities_may_conflict_p(le, re);
551  }
552  return intersect_p;
553 }

References cell_any_reference(), cell_equal_p(), entities_may_conflict_p(), and reference_variable.

Referenced by equal_condition_to_points_to().

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

◆ points_to_cells_minimal_module_upper_bound()

entity points_to_cells_minimal_module_upper_bound ( list  )

◆ points_to_cells_minimal_reference_upper_bound()

reference points_to_cells_minimal_reference_upper_bound ( entity  ,
type  ,
list   
)

◆ points_to_cells_minimal_type_upper_bound()

type points_to_cells_minimal_type_upper_bound ( list  )

◆ points_to_cells_minimal_upper_bound()

cell points_to_cells_minimal_upper_bound ( list  )

Referenced by fuse_points_to_sink_cells().

+ Here is the caller graph for this function:

◆ points_to_cells_to_upper_bound_points_to_cells()

list points_to_cells_to_upper_bound_points_to_cells ( list  cl)

Add to list "l" cells that are upper bound cells of the cells already in list "l" and return list "l".

Parameters
cll

Definition at line 1007 of file points_to.c.

1008 {
1009  list ubl = NIL;
1010  FOREACH(CELL, c, cl) {
1012  ubl = gen_nconc(ubl, cubl);
1013  }
1014  ubl = gen_nconc(cl, ubl);
1015  return ubl;
1016 }
list points_to_cell_to_upper_bound_points_to_cells(cell c)
Return a list of cells that are larger than cell "c" in the points-to cell lattice.
Definition: points_to.c:973

References CELL, FOREACH, gen_nconc(), NIL, and points_to_cell_to_upper_bound_points_to_cells().

+ Here is the call graph for this function:

◆ points_to_compare_cells()

int points_to_compare_cells ( const void *  vpt1,
const void *  vpt2 
)

Comparison of two points-to arcs based on their source and sink nodes.

This comparison function is used to sort a list of points-to before storage and print-out.

It must return -1, 0 or 1 like strcmp(). It should avoid 0 because we want a total order to avoid validation problems. Hence the exploitation of the references, number of indices, subscript expressions, etc. if the entity names are not sufficient to disambiguate the references.

When subscript expressions are used, fields are replaced by the corresponding field number. So the sort is based on the field ranks in the data structure and not on the the field names.

For abstract locations, the local name is used for the sort and the global names is sometimes used in the prettyprint. Hence, the alphabetical order is not obvious in the print-out.

Parameters
vpt1pt1
vpt2pt2

Definition at line 295 of file prettyprint.c.

296 {
297  int i = 0;
298 
299  points_to pt1 = *((points_to *) vpt1);
300  points_to pt2 = *((points_to *) vpt2);
301 
302  cell c1so = points_to_source(pt1);
303  cell c2so = points_to_source(pt2);
304  cell c1si = points_to_sink(pt1);
305  cell c2si = points_to_sink(pt2);
306 
307  //cell c1 = CELL(CAR(vc1));
308  //cell c2 = CELL(CAR(vc2));
309  // FI: bypass of GAP case
310  reference r1so = cell_to_reference(c1so);
311  reference r2so = cell_to_reference(c2so);
312  reference r1si = cell_to_reference(c1si);
313  reference r2si = cell_to_reference(c2si);
314 
315  entity v1so = reference_variable(r1so);
316  entity v2so = reference_variable(r2so);
317  entity v1si = reference_variable(r1si);
319  list sl1 = NIL, sl2 = NIL, sli1 = NIL, sli2 = NIL ;
320  // FI: memory leak? generation of a new string?
321  extern const char* entity_minimal_user_name(entity);
322  string n1so = entity_abstract_location_p(v1so)?
324  string n2so = entity_abstract_location_p(v2so)?
326  string n1si = entity_abstract_location_p(v1si)?
328  string n2si = entity_abstract_location_p(v2si)?
330 
331  i = strcmp(n1so, n2so);
332  if(i==0) {
333  i = strcmp(n1si, n2si);
334  if(i==0) {
335  sl1 = reference_indices(r1so);
336  sl2 = reference_indices(r2so);
337  int i1 = gen_length(sl1);
338  int i2 = gen_length(sl2);
339 
340  i = i2>i1? 1 : (i2<i1? -1 : 0);
341 
342  if(i==0) {
343  sli1 = reference_indices(r1si);
344  sli2 = reference_indices(r2si);
345  int i1 = gen_length(sli1);
346  int i2 = gen_length(sli2);
347 
348  i = i2>i1? 1 : (i2<i1? -1 : 0);
349  // if(i==0) {
350  for(;i==0 && !ENDP(sl1); POP(sl1), POP(sl2)){
351  expression se1 = EXPRESSION(CAR(sl1));
352  expression se2 = EXPRESSION(CAR(sl2));
354  int i1 = expression_to_int(se1);
355  int i2 = expression_to_int(se2);
356  i = i2>i1? -11 : (i2<i1? 1 : 0);
357  } else {
358  string s1 = expression_to_string(se1);
359  string s2 = expression_to_string(se2);
360  i = strcmp(s1, s2);
361  }
362  }
363  // if(i==0) {
364  // i = strcmp(entity_minimal_user_name(v1si), entity_minimal_user_name(v2si));
365  for(;i==0 && !ENDP(sli1); POP(sli1), POP(sli2)){
366  expression sei1 = EXPRESSION(CAR(sli1));
367  expression sei2 = EXPRESSION(CAR(sli2));
368  if(expression_constant_p(sei1) && expression_constant_p(sei2)){
369  int i1 = expression_to_int(sei1);
370  int i2 = expression_to_int(sei2);
371  i = i2>i1? -1 : (i2<i1? 1 : 0);
372  } else {
373  // FI: memory leak?
374  string s1 = expression_to_string(sei1);
375  string s2 = expression_to_string(sei2);
376  i = strcmp(s1, s2);
377  }
378  }
379  }
380  }
381  }
382  // }
383  return i;
384 }
__m64 v2si
Definition: 3dnow.h:7
reference cell_to_reference(cell)
FI: probably to be moved elsewhere in ri-util.
Definition: effects.c:1326
const char * entity_minimal_user_name(entity e)
Do not preserve scope information.
Definition: naming.c:223

References CAR, cell_to_reference(), ENDP, entity_abstract_location_p(), entity_local_name(), entity_minimal_user_name(), EXPRESSION, expression_constant_p(), expression_to_int(), expression_to_string(), gen_length(), NIL, points_to_sink, points_to_source, POP, reference_indices, reference_variable, and s1.

Referenced by fi_points_to_storage(), init_points_to_analysis(), points_to_list_sort(), and points_to_storage().

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

◆ points_to_expression_to_concrete_type()

type points_to_expression_to_concrete_type ( expression  e)

The type returned is stored in a hash-table.

It should not be freed. See compute_basic_concrete_type().

This function is useful to avoid the conditional free.

Definition at line 617 of file type.c.

618 {
619  bool to_be_freed;
620  type t = points_to_expression_to_type(e, &to_be_freed);
622  if(to_be_freed) free_type(t);
623  return ct;
624 }
type points_to_expression_to_type(expression e, bool *to_be_freed)
FI: I need more generality than is offered by expression_to_type() because fields are assimilated to ...
Definition: type.c:592

References compute_basic_concrete_type(), free_type(), and points_to_expression_to_type().

Referenced by binary_intrinsic_call_to_points_to_sinks(), expression_to_points_to_cells(), freed_list_to_points_to(), intrinsic_call_condition_to_points_to(), intrinsic_call_to_points_to(), memory_dereferencing_p(), semantics_expression_to_points_to_sinks(), and unary_intrinsic_call_to_points_to_sinks().

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

◆ points_to_expression_to_pointed_type()

type points_to_expression_to_pointed_type ( expression  e)

Return a new allocated type "t" of the address pointed by expression "e", if expression "e" denotes an address.

"t" should not be freed.

We should return a pointer towards an array of dimension n-1. The first dimension is lost.

Build the pointed type, copy of cet except for its first dimension

Build the poiinter type

Definition at line 631 of file type.c.

632 {
633  type t = type_undefined;
634  bool to_be_freed;
635  type et = points_to_expression_to_type(e, &to_be_freed);
637  if(to_be_freed) free_type(et);
638 
639  if(pointer_type_p(cet)) {
640  type pt = type_to_pointed_type(cet);
642  }
643  else if(array_type_p(cet)) {
644  /* We should return a pointer towards an array of dimension
645  n-1. The first dimension is lost. */
646  variable cet_v = type_variable(cet);
647  list cet_v_dl = variable_dimensions(cet_v);
648  /* Build the pointed type, copy of cet except for its first dimension */
649  list ndl = gen_full_copy_list(CDR(cet_v_dl));
650  basic nat_b = copy_basic(variable_basic(cet_v));
651  variable nat_v = make_variable(nat_b, ndl, NIL);
652  type nat = make_type_variable(nat_v);
653  /* Build the poiinter type*/
654  // variable v = type_variable(nat);
655  basic b = make_basic_pointer(nat);
656  variable v = make_variable(b, NIL, NIL);
657  t = make_type_variable(v);
658  }
659  else
660  pips_internal_error("Arg. is not in definition domain.\n");
661  return t;
662 }
basic make_basic_pointer(type _field_)
Definition: ri.c:179

References array_type_p(), CDR, compute_basic_concrete_type(), copy_basic(), copy_type(), free_type(), gen_full_copy_list(), make_basic_pointer(), make_type_variable(), make_variable(), NIL, pips_internal_error, pointer_type_p(), points_to_expression_to_type(), type_to_pointed_type(), type_undefined, type_variable, variable_basic, and variable_dimensions.

Referenced by expression_to_points_to_sinks_with_offset(), and unary_intrinsic_call_to_points_to_sinks().

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

◆ points_to_expression_to_type()

type points_to_expression_to_type ( expression  e,
bool to_be_freed 
)

FI: I need more generality than is offered by expression_to_type() because fields are assimilated to subscripts.

In order to type t[*] as well as t[0]...

Parameters
to_be_freedo_be_freed

Definition at line 592 of file type.c.

593 {
594  type t = type_undefined;
595  syntax s = expression_syntax(e);
596  if(syntax_reference_p(s)) {
598  t = points_to_reference_to_type(r, to_be_freed);
599  }
600  else {
601  /* In order to type t[*] as well as t[0]... */
602  expression ne = copy_expression(e);
604  *to_be_freed = true;
605  t = expression_to_type(ne);
606  free_expression(ne);
607  }
608 
609  return t;
610 }
static expression eliminate_calls_to_unbounded(expression e)
Allocate a copy of expression "e" where calls to the unbounded function are replaced by calls to the ...
Definition: type.c:584
type expression_to_type(expression exp)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486

References copy_expression(), eliminate_calls_to_unbounded(), expression_syntax, expression_to_type(), free_expression(), points_to_reference_to_type(), syntax_reference, syntax_reference_p, and type_undefined.

Referenced by assignment_to_points_to(), check_rhs_value_types(), expression_to_points_to_sources(), pointer_arithmetic_to_points_to(), points_to_expression_to_concrete_type(), points_to_expression_to_pointed_type(), and subscript_to_points_to_sinks().

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

◆ points_to_list_sort()

list points_to_list_sort ( list  ptl)

Allocate a copy of ptl and sort it.

It might be better to admit a side effect on ptl and to let the caller copy the liste before sorting.

(gen_cmp_func_t)

Parameters
ptltl

Definition at line 389 of file prettyprint.c.

390 {
391  list sptl = gen_full_copy_list(ptl);
392 
393  gen_sort_list(sptl, /* (gen_cmp_func_t) */ points_to_compare_cells);
394 
395  return sptl;
396 }
int points_to_compare_cells(const void *vpt1, const void *vpt2)
Comparison of two points-to arcs based on their source and sink nodes.
Definition: prettyprint.c:295
void gen_sort_list(list l, gen_cmp_func_t compare)
Sorts a list of gen_chunks in place, to avoid allocations...
Definition: list.c:796

References gen_full_copy_list(), gen_sort_list(), and points_to_compare_cells().

Referenced by text_points_to_relations(), and words_points_to_list().

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

◆ points_to_reference_included_p()

bool points_to_reference_included_p ( reference  r1,
reference  r2 
)

FI->FC/AM: some elements of the lattice must be exploited here...

Parameters
r11
r22

Definition at line 1243 of file effects.c.

1244 {
1245  bool included_p = true;
1246  entity v1 = reference_variable(r1);
1247  entity v2 = reference_variable(r2);
1248 
1249  list dims1 = reference_indices(r1);
1250  list dims2 = reference_indices(r2);
1251 
1252  if(v1 == v2) {
1253  if(gen_length(dims1)==gen_length(dims2)) {
1254  list cdims2 = dims2;
1255  FOREACH(EXPRESSION, s1, dims1) {
1256  expression s2 = EXPRESSION(CAR(cdims2));
1257  if(!expression_equal_p(s1,s2)) {
1258  if(!unbounded_expression_p(s2)) {
1259  included_p = false;
1260  break;
1261  }
1262  }
1263  cdims2 = CDR(cdims2);
1264  }
1265  }
1266  else if(gen_length(dims1)>gen_length(dims2)) {
1267  list cdims1 = dims1;
1268  FOREACH(EXPRESSION, s2, dims2) {
1269  expression s1 = EXPRESSION(CAR(cdims1));
1270  if(!expression_equal_p(s1,s2)) {
1271  if(!unbounded_expression_p(s2)) {
1272  included_p = false;
1273  break;
1274  }
1275  }
1276  cdims1 = CDR(cdims1);
1277  }
1278  }
1279  else {
1280  included_p = false;
1281  }
1282  }
1283  else {
1284  // pips_internal_error("Abstract location lattice not implemented here.\n");
1285  // FI->AM/FC: you should check the inclusion of abstract_location(v1) and
1286  // abstract_location(v2)...
1287  included_p = false;
1288  }
1289  return included_p;
1290 }

References CAR, CDR, EXPRESSION, expression_equal_p(), FOREACH, gen_length(), reference_indices, reference_variable, s1, and unbounded_expression_p().

Referenced by cell_included_p().

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

◆ points_to_reference_to_concrete_type()

◆ points_to_reference_to_final_dimension()

int points_to_reference_to_final_dimension ( reference  r)

Compute the number of array subscript at the end of a points_to_reference.

Look for the last field subscript and count the number of subscripts after it. If no field susbcript is found, then all subscripts are final array subscripts.

To make thinks easier, the subscript list is reversed.

Definition at line 244 of file points_to.c.

245 {
246  list sl = reference_indices(r);
247  sl = gen_nreverse(sl);
248  int d = 0;
249  FOREACH(EXPRESSION, e, sl) {
251  break;
252  else
253  d++;
254  }
255  sl = gen_nreverse(sl);
256  reference_indices(r) = sl;
257  return d;
258 }

References EXPRESSION, field_reference_expression_p(), FOREACH, gen_nreverse(), and reference_indices.

+ Here is the call graph for this function:

◆ points_to_reference_to_type()

type points_to_reference_to_type ( reference  ref,
bool to_be_freed 
)

FI: I need more generality than is offered by cell_to_type()

Maybe because of fields.

Surely because of implicit arrays linked to scalar pointers

Parameters
refef
to_be_freedo_be_freed

Definition at line 527 of file type.c.

528 {
529  type t = type_undefined;
530 
532  list sl = reference_indices(ref);
533 
534  if(ENDP(sl)) {
535  t = entity_type(v);
536  *to_be_freed = false;
537  }
538  else {
539  int ns = (int) gen_length(sl);
540  expression fs = EXPRESSION(CAR(sl));
541  bool int_p = expression_integer_constant_p(fs);
542  // FI: faire un cas particulier pour des cas comme i[1] ou i est un scalaire?
543  // FI: I do not know what can happen with struct objects; they are
544  // scalar, a dimension may be added and nevertheless a field may be
545  // accessed....
546  if(entity_scalar_p(v) && ns==1 && int_p) {
547  *to_be_freed = false;
548  t = entity_type(v);
549  }
550  else {
551  expression ls = EXPRESSION(CAR(gen_last(sl)));
552  syntax lss = expression_syntax(ls);
553  if(syntax_reference_p(lss)) {
554  reference r = syntax_reference(lss);
556  if(entity_field_p(f)) {
557  t = entity_type(f);
558  *to_be_freed = false;
559  }
560  }
561  }
562  }
563 
564  if(type_undefined_p(t))
565  t = cell_reference_to_type(ref, to_be_freed);
566 
567  return t;
568 }
bool expression_integer_constant_p(expression e)
Definition: expression.c:2417
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113

References CAR, cell_reference_to_type(), ENDP, entity_field_p(), entity_scalar_p(), entity_type, EXPRESSION, expression_integer_constant_p(), expression_syntax, f(), gen_last(), gen_length(), int, ref, reference_indices, reference_variable, syntax_reference, syntax_reference_p, type_undefined, and type_undefined_p.

Referenced by adapt_reference_to_type(), create_scalar_stub_sink_cell(), gen_may_constant_paths(), gen_must_constant_paths(), opkill_may_constant_path(), opkill_must_constant_path(), points_to_cell_to_type(), points_to_expression_to_type(), points_to_reference_to_concrete_type(), points_to_reference_to_typed_index(), and reference_add_field_dimension().

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

◆ points_to_reference_to_typed_index()

list points_to_reference_to_typed_index ( reference  r,
type  t 
)

Look for the index in "r" that corresponds to a pointer of type "t" and return the corresponding element list.

In other words, the type of "&r" is "t".

It is done in a very inefficient way

Definition at line 361 of file points_to.c.

362 {
363  bool to_be_freed;
364  type rt = points_to_reference_to_type(r, &to_be_freed);
365  list rsl = reference_indices(r); // reference subscript list
366  pips_assert("t is a pointer type", C_pointer_type_p(t));
368  list psl = list_undefined; // pointed subscript list
369 
370  if(array_pointer_type_equal_p(rt, pt))
371  psl = gen_last(rsl);
372  else {
373  if(to_be_freed) free_type(rt);
374  entity v = reference_variable(r);
375  list nl = NIL;
376  int i;
377  int n = (int) gen_length(rsl);
378  reference nr = make_reference(v, nl);
379  bool found_p = false;
380 
381  for(i=0;i<n;i++) {
382  nl = gen_nconc(nl, CONS(EXPRESSION,
384  NIL));
385  reference_indices(nr) = nl;
386  rt = points_to_reference_to_type(nr, &to_be_freed);
387  if(array_pointer_type_equal_p(rt, pt)) {
388  found_p = true;
389  break;
390  }
391  }
392 
393  free_reference(nr);
394 
395  if(found_p)
396  psl = gen_nthcdr(i, rsl);
397  else {
398  // The issue may be due to a user bug, as was the case in
399  // Strict_typing.sub/malloc03.c
400  if(entity_heap_location_p(v)) {
401  // It would be nice to have a current statement stack...
402  pips_user_error("The dynamic allocation of \"%s\" is likely "
403  "to be inadequate with its use in the current "
404  "statement.\n", entity_local_name(v));
405  }
406  else
407  pips_internal_error("Type not found.\n");
408  }
409  }
410 
411  free_type(pt);
412 
413  return psl;
414 }
type points_to_reference_to_type(reference, bool *)
FI: I need more generality than is offered by cell_to_type()
Definition: type.c:527
list gen_nthcdr(int n, const list lx)
caution: the first item is 0! was: return( (n<=0) ? l : gen_nthcdr( n-1, CDR( l ))) ; if n>gen_length...
Definition: list.c:700
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
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
bool C_pointer_type_p(type)
Returns OK for "char[]" as well as for "char *".
Definition: type.c:3011

References array_pointer_type_equal_p(), C_pointer_type_p(), C_type_to_pointed_type(), CONS, copy_expression(), entity_heap_location_p(), entity_local_name(), EXPRESSION, free_reference(), free_type(), gen_last(), gen_length(), gen_nconc(), gen_nth(), gen_nthcdr(), int, list_undefined, make_reference(), NIL, pips_assert, pips_internal_error, pips_user_error, points_to_reference_to_type(), reference_indices, and reference_variable.

Referenced by offset_array_reference().

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

◆ points_to_reference_update_final_subscripts()

void points_to_reference_update_final_subscripts ( reference  r,
list  nsl 
)

Substitute the subscripts "sl" in points-to reference "r" just after the last field subscript by "nsl".

"sl" must be broken into three parts, possibly empty:

  1. The first part that ends up at the last field reference. It may be empty when no field is referenced.
  2. The second part that starts just after the last field reference and that counts at most as many elements as the new subscript list, "nsl". This part must be substituted.
  3. The third part that is left unchanged after substitution.

Issue: how do you know that the initial array subscript must be preserved because it is an implicit dimension added for pointer arithmetics?

build sl1

Parameters
nslsl

Definition at line 278 of file points_to.c.

279 {
280  list sl = reference_indices(r);
281  list sl1 = NIL, sl3 = NIL, sl23 = NIL;
282 
283  sl = gen_nreverse(sl); // sl1 and sl23 are built in the right order
284  bool found_p = false;
285  bool skip_one_p = false; // to skip indices added for pointer arithmetic
286  FOREACH(EXPRESSION, e, sl) {
288  type et = expression_to_type(e);
289  if(pointer_type_p(et))
290  skip_one_p = true;
291  found_p = true;
292  free_type(et);
293  }
294  if(found_p) {
295  /* build sl1 */
296  sl1 = CONS(EXPRESSION, e , sl1);
297  }
298  else
299  sl23 = CONS(EXPRESSION, e , sl23);
300  }
301 
302  if(skip_one_p && ENDP(sl23) && !ENDP(nsl)) {
303  pips_internal_error("We are not generating a memory access constant path.\n");
304  }
305 
306  // FI: place the new indices as early as possible
307 #if 0
308  int n = (int) gen_length(nsl);
309  int i = 0;
310  FOREACH(EXPRESSION, e, sl23) {
311  if(skip_one_p) {
312  sl1 = gen_nconc(sl1, CONS(EXPRESSION, e , NIL));
313  skip_one_p = false;
314  }
315  else {
316  if(i<n)
317  free_expression(e);
318  else
319  sl3 = gen_nconc(sl3, CONS(EXPRESSION, e, NIL));
320  i++;
321  }
322  }
323 
324  sl = gen_nconc(sl1, nsl);
325  sl = gen_nconc(sl, sl3);
326 #endif
327 
328  // FI: place the new indices as late as possible
329  int n = (int) gen_length(nsl);
330  int n23 = (int) gen_length(sl23);
331  int i = 0;
332  FOREACH(EXPRESSION, e, sl23) {
333  if(i>=n23-n)
334  free_expression(e);
335  else
336  sl3 = gen_nconc(sl3, CONS(EXPRESSION, e, NIL));
337  i++;
338  }
339 
340  sl = gen_nconc(sl1, sl3);
341  sl = gen_nconc(sl, nsl);
342 
343  gen_free_list(sl23);
344  reference_indices(r) = sl;
345 
346  // We do not want to generate indirection in the reference
347  // The exactitude information is not relevant here
348  // bool exact_p;
349  // pips_assert("The reference is a constant memory access path",
350  // !effect_reference_dereferencing_p( r, &exact_p));
351  // Might only work for standard references and not for points-to
352  // references: core dumps with points-to references.
353 }

References CONS, ENDP, EXPRESSION, expression_to_type(), field_reference_expression_p(), FOREACH, free_expression(), free_type(), gen_free_list(), gen_length(), gen_nconc(), gen_nreverse(), int, NIL, pips_internal_error, pointer_type_p(), and reference_indices.

Referenced by subscript_to_points_to_sinks().

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

◆ points_to_sink_cell_compatible_p()

bool points_to_sink_cell_compatible_p ( cell  )

◆ points_to_source_cell_compatible_p()

bool points_to_source_cell_compatible_p ( cell  c)

Definition at line 1241 of file type.c.

1242 {
1243  bool compatible_p = true;
1244 
1245  if(nowhere_cell_p(c))
1246  compatible_p = false;
1247  else if(null_cell_p(c))
1248  compatible_p = false;
1249 
1250  return compatible_p;
1251 }

References nowhere_cell_p(), and null_cell_p().

Referenced by points_to_cell_types_compatibility().

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

◆ points_to_with_stripped_sink()

points_to points_to_with_stripped_sink ( points_to  pt,
int(*)(void)  line_number_func 
)

The value of the source can often be expressed with different subscript lists.

For instance, a, a[0], a[0][0] have different types but the same value if a is a 2-D array.

This function allocated a new points-to object whose sink has a minimal number of indices.

FI: I have added this function to deal with pointers to arrays. It is called from generic_reference_to_points_to_matching_list() to try to adapt the points-to information to the undefined requirements of Beatrice's functions for regions_with_points_to. I do not think the function below is correct when structs are involved... The stripping may be useful, but it should be much more careful.

adapt_reference_to_type() might be better here to adjust the subscripts in sink.

Add the implicit dimension

Dealing with the special case of a constant p -> "foo"

The other option would be to accept "foo"[0] as a valid reference... Extending references to constant functions is a first step...

Parameters
ptt

Definition at line 1074 of file points_to.c.

1076 {
1077  cell source = points_to_source(pt);
1078  cell sink = points_to_sink(pt);
1079  cell new_sink_cell = cell_undefined;
1080 
1081  // FI: first implementation
1082  if(false) {
1083  reference source_r = cell_any_reference(source);
1084  list source_sl = reference_indices(source_r);
1085  list c_source_sl = list_undefined;
1086 
1087  reference sink_r = cell_any_reference(sink);
1088  // FI: sink_sl is longer than source_sl if pt is semantically correct
1089  list sink_sl = reference_indices(sink_r);
1090  list c_sink_sl = list_undefined;
1091  entity sink_e = reference_variable(sink_r);
1092 
1093  list new_sink_sl = NIL;
1094  for(c_source_sl = source_sl, c_sink_sl = sink_sl;
1095  !ENDP(c_source_sl);
1096  POP(c_source_sl), POP(c_sink_sl)) {
1097  expression s = copy_expression(EXPRESSION(CAR(c_sink_sl)));
1098  new_sink_sl = CONS(EXPRESSION, s, new_sink_sl);
1099  }
1100  if(!get_bool_property("POINTS_TO_STRICT_POINTER_TYPES")
1101  && !anywhere_cell_p(sink)
1103  && !ENDP(c_sink_sl)) {
1104  /* Add the implicit dimension */
1105  expression s = copy_expression(EXPRESSION(CAR(c_sink_sl)));
1106  new_sink_sl = CONS(EXPRESSION, s, new_sink_sl);
1107  }
1108  new_sink_sl = gen_nreverse(new_sink_sl);
1109 
1110  new_sink_cell = make_cell_reference(make_reference(sink_e, new_sink_sl));
1111  }
1112  else {
1113  // Second implementation
1115  || null_cell_p(sink) || nowhere_cell_p(sink)
1116  // FI: why is the typed heap cell not handled too?
1117  || heap_cell_p(sink)) {
1118  new_sink_cell = copy_cell(sink);
1119  }
1120  else {
1121  new_sink_cell = copy_cell(sink);
1122  reference n_sink_r = cell_any_reference(new_sink_cell);
1123  type source_t = points_to_cell_to_concrete_type(source);
1124  if(pointer_type_p(source_t)) {
1125  type source_pt = type_to_pointed_type(source_t);
1126  if(adapt_reference_to_type(n_sink_r, source_pt, line_number_func))
1127  ;
1128  else {
1129  /* Dealing with the special case of a constant p -> "foo"
1130  *
1131  * The other option would be to accept "foo"[0] as a valid
1132  * reference... Extending references to constant functions
1133  * is a first step...
1134  */
1135  bool ok_p = false;
1136  type sink_t = points_to_reference_to_concrete_type(n_sink_r);
1137  if(char_type_p(source_pt)) {
1139  ok_p = true;
1140  }
1141  if(!ok_p)
1142  pips_internal_error("The type of a sink cell, \"%s\", is not compatible with the source cell, \"%s\".\n",
1143  safe_type_to_string(sink_t),
1144  safe_type_to_string(source_t));
1145  }
1146  }
1147 
1148  else
1149  pips_internal_error("The type of a source cell is not a pointer.\n");
1150  }
1151  }
1152 
1153  points_to npt = make_points_to(copy_cell(source),
1154  new_sink_cell,
1157  return npt;
1158 }
approximation copy_approximation(approximation p)
APPROXIMATION.
Definition: effects.c:132
cell copy_cell(cell p)
CELL.
Definition: effects.c:246
points_to make_points_to(cell a1, cell a2, approximation a3, descriptor a4)
bool cell_typed_anywhere_locations_p(cell c)
test if a cell is the bottom of the lattice
bool adapt_reference_to_type(reference, type, int(*)(void))
FI: a really stupid function...
Definition: type.c:1327
#define cell_undefined
Definition: effects.h:430
bool char_star_constant_function_type_p(type)
Beware of typedefs.
Definition: type.c:5787
string safe_type_to_string(const type)
Definition: type.c:59
bool char_type_p(type)
return true whether ‘t’ is a char or an unsigned char
Definition: type.c:2877

References adapt_reference_to_type(), anywhere_cell_p(), CAR, cell_any_reference(), cell_typed_anywhere_locations_p(), cell_undefined, char_star_constant_function_type_p(), char_type_p(), CONS, copy_approximation(), copy_cell(), copy_expression(), ENDP, EXPRESSION, gen_nreverse(), get_bool_property(), heap_cell_p(), list_undefined, make_cell_reference(), make_descriptor_none(), make_points_to(), make_reference(), NIL, nowhere_cell_p(), null_cell_p(), pips_internal_error, pointer_type_p(), points_to_approximation, points_to_cell_to_concrete_type(), points_to_reference_to_concrete_type(), points_to_sink, points_to_source, POP, reference_indices, reference_variable, safe_type_to_string(), and type_to_pointed_type().

Referenced by generic_reference_to_points_to_matching_list().

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

◆ points_to_words_reference()

list points_to_words_reference ( reference  r)

Specific handling of references appearing in points_to.

Definition at line 232 of file prettyprint.c.

233 {
234  extern const char* entity_minimal_user_name(entity);
235 
236  // Normal implementation, used for validation:
238  // To ease debugging, use:
239  //return words_any_reference(r, NIL, entity_full_name);
240 }
list Words_Any_Reference(reference obj, list pdl, const char *(*enf)(entity))
Definition: misc.c:773

References entity_minimal_user_name(), NIL, and Words_Any_Reference().

Referenced by word_points_to().

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

◆ print_pointer_value()

void print_pointer_value ( cell_relation  pv)
Parameters
pvv

Definition at line 615 of file prettyprint.c.

616 {
617  text t = text_pointer_value(pv);
618  print_text(stderr, t);
619  free_text(t);
620 }
void free_text(text p)
Definition: text.c:74
text text_pointer_value(cell_relation pv)
text text_region(effect reg) input : a region output : a text consisting of several lines of commenta...
Definition: prettyprint.c:480
void print_text(FILE *fd, text t)
Definition: print.c:195

References free_text(), print_text(), and text_pointer_value().

Referenced by print_pointer_values().

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

◆ print_pointer_values()

void print_pointer_values ( list  lpv)
Parameters
lpvpv

Definition at line 622 of file prettyprint.c.

623 {
624  fprintf(stderr,"\n");
625  if (ENDP(lpv))
626  fprintf(stderr,"<none>");
627  else
628  {
629  FOREACH(CELL_RELATION, pv, lpv)
630  {
632  }
633  }
634  fprintf(stderr,"\n");
635 }
void print_pointer_value(cell_relation pv)
Definition: prettyprint.c:615

References CELL_RELATION, ENDP, FOREACH, fprintf(), and print_pointer_value().

Referenced by print_pv_results().

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

◆ print_points_to_cell()

void print_points_to_cell ( cell  c)

Debug: use stderr.

Definition at line 196 of file points_to.c.

197 {
198  fprint_points_to_cell(stderr, c);
199 }
void fprint_points_to_cell(FILE *f __attribute__((unused)), cell c)
Debug: print a cell list for points-to.
Definition: points_to.c:178

References fprint_points_to_cell().

Referenced by print_points_to_cells().

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

◆ print_points_to_cells()

void print_points_to_cells ( list  cl)

Debug.

Parameters
cll

Definition at line 202 of file points_to.c.

203 {
204  if(ENDP(cl))
205  fprintf(stderr, "Empty cell list");
206  else {
208  FOREACH(CELL, c, cl) {
210  entity v = reference_variable(r);
211  /* *ANY_MODULE* is unfortunately not an entity... */
213  if(!entity_undefined_p(mv) && m!=mv)
214  fprintf(stderr,"%s" MODULE_SEP_STRING, entity_local_name(mv));
216  if(!ENDP(CDR(cl)))
217  fprintf(stderr, ", ");
218  }
219  }
220  fprintf(stderr, "\n");
221 }
void print_points_to_cell(cell c)
Debug: use stderr.
Definition: points_to.c:196

References CDR, CELL, cell_any_reference(), ENDP, entity_local_name(), entity_module_name(), entity_undefined_p, FOREACH, fprintf(), get_current_module_entity(), module_name_to_entity(), MODULE_SEP_STRING, print_points_to_cell(), and reference_variable.

+ Here is the call graph for this function:

◆ pt_to_list_undefined_p()

◆ pv_cells_mergeable_p()

bool pv_cells_mergeable_p ( cell_relation  pv1,
cell_relation  pv2 
)

value_of pvs, try to see if their cells are inverted

Parameters
pv1v1
pv2v2

Definition at line 230 of file pointer_values.c.

231 {
232 
233 
234  bool value_of_1_p = cell_relation_second_value_of_p(pv1);
235  bool value_of_2_p = cell_relation_second_value_of_p(pv1);
236 
237  if ( (value_of_1_p && !value_of_2_p) || (value_of_2_p && !value_of_1_p))
238  return false;
239 
240  cell c_first_1 = cell_relation_first_cell(pv1);
241  cell c_second_1 = cell_relation_second_cell(pv1);
242 
243  cell c_first_2 = cell_relation_first_cell(pv2);
244  cell c_second_2 = cell_relation_second_cell(pv2);
245 
246  int n_first_first = cell_compare(&c_first_1, &c_first_2);
247 
248  if (n_first_first == 0)
249  {
250  int n_second_second = cell_compare(&c_second_1, &c_second_2);
251 
252  if (n_second_second != 0)
253  {
254  if (cell_entity(c_second_1) != cell_entity(c_second_2)
257  return false;
258  }
259  }
260  else
261  {
262  if (!value_of_1_p)
263  return false;
264  else /* value_of pvs, try to see if their cells are inverted */
265  {
266  int n_first_second = cell_compare(&c_first_1, &c_second_2);
267  if (n_first_second == 0)
268  {
269  int n_second_first = cell_compare(&c_second_1, &c_first_2);
270 
271  if (n_second_first != 0)
272  return false;
273  }
274  else
275  return false;
276 
277  }
278  }
279 
282 
283  if (descriptor_none_p(d1) && descriptor_none_p(d2))
284  {
285  return true;
286  }
287  else
288  pips_internal_error("Convex pointer_values not implemented yet");
289 
290  return false;
291 }
#define cell_relation_descriptor(x)
Definition: effects.h:517
#define descriptor_none_p(x)
Definition: effects.h:602

References cell_any_reference(), cell_compare(), cell_entity(), cell_relation_descriptor, cell_relation_first_cell, cell_relation_second_cell, cell_relation_second_value_of_p, descriptor_none_p, gen_length(), pips_internal_error, and reference_indices.

Referenced by pvs_union_combinable_p().

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

◆ pv_cells_syntactically_equal_p()

bool pv_cells_syntactically_equal_p ( cell_relation  pv1,
cell_relation  pv2 
)

value_of pvs, try to see if their cells are inverted

Parameters
pv1v1
pv2v2

Definition at line 162 of file pointer_values.c.

163 {
164 
165 
166  bool value_of_1_p = cell_relation_second_value_of_p(pv1);
167  bool value_of_2_p = cell_relation_second_value_of_p(pv1);
168 
169  if ( (value_of_1_p && !value_of_2_p) || (value_of_2_p && !value_of_1_p))
170  return false;
171 
172  cell c_first_1 = cell_relation_first_cell(pv1);
173  cell c_second_1 = cell_relation_second_cell(pv1);
174 
175  cell c_first_2 = cell_relation_first_cell(pv2);
176  cell c_second_2 = cell_relation_second_cell(pv2);
177 
178  int n_first_first = cell_compare(&c_first_1, &c_first_2);
179 
180  if (n_first_first == 0)
181  {
182  int n_second_second = cell_compare(&c_second_1, &c_second_2);
183 
184  if (n_second_second != 0)
185  return false;
186  }
187  else
188  {
189  if (!value_of_1_p)
190  return false;
191  else /* value_of pvs, try to see if their cells are inverted */
192  {
193  int n_first_second = cell_compare(&c_first_1, &c_second_2);
194  if (n_first_second == 0)
195  {
196  int n_second_first = cell_compare(&c_second_1, &c_first_2);
197 
198  if (n_second_first != 0)
199  return false;
200  }
201  else
202  return false;
203 
204  }
205  }
206 
209 
210  if (descriptor_none_p(d1) && descriptor_none_p(d2))
211  {
212  return true;
213  }
214  else
215  pips_internal_error("Convex pointer_values not implemented yet");
216 
217  return false;
218 }

References cell_compare(), cell_relation_descriptor, cell_relation_first_cell, cell_relation_second_cell, cell_relation_second_value_of_p, descriptor_none_p, and pips_internal_error.

Referenced by simple_pvs_syntactically_equal_p().

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

◆ recursive_cell_to_pointer_cells()

list recursive_cell_to_pointer_cells ( cell  c)

Go down if it is an array of pointers or an array of struct

add indices to cell c

Add subscripts to reach array elements

Look for fields that are either pointers, or arrays or structs

Add field subscript to reference

Definition at line 1680 of file effects.c.

1681 {
1682  list children = NIL;
1683  // Too strong for recursive calls
1684  //pips_assert("Cell \"c\" has no subscripts.",
1685  // ENDP(reference_indices(cell_any_reference(c))));
1686  bool to_be_freed;
1687  type ct = points_to_cell_to_type(c, &to_be_freed);
1688 
1689  if(pointer_type_p(ct)) {
1690  children = CONS(CELL, copy_cell(c), NIL);
1691  }
1692  else if(array_type_p(ct)) {
1693  /* Go down if it is an array of pointers or an array of struct */
1695  /* add indices to cell c */
1696  cell n_c = copy_cell(c);
1697  /* Add subscripts to reach array elements */
1699  children = recursive_cell_to_pointer_cells(n_c);
1700  free_cell(n_c);
1701  }
1702  else {
1703  ; // No children
1704  }
1705  }
1706  else if(struct_type_p(ct)) {
1707  /* Look for fields that are either pointers, or arrays or structs */
1709  entity dte = basic_derived(b);
1710  type dt = entity_type(dte);
1711  list fields = type_struct(dt);
1712  FOREACH(ENTITY, f, fields) {
1714  if(pointer_type_p(ft)
1715  || array_type_p(ft)
1716  || struct_type_p(ft)) {
1717  cell n_c = copy_cell(c);
1718  /* Add field subscript to reference */
1720  children = recursive_cell_to_pointer_cells(n_c);
1721  free_cell(n_c);
1722  }
1723  }
1724  }
1725 
1726  // Too strong for recursive calls
1727  //pips_assert("Cell \"c\" has children, "
1728  // "or this function would not have been called.", !ENDP(children));
1729  return children;
1730 }
void points_to_cell_add_unbounded_subscripts(cell c)
Definition: effects.c:1632
cell points_to_cell_add_field_dimension(cell c, entity f)
Functions about points-to cells - There is no cell.c file.
Definition: effects.c:1444
void free_cell(cell p)
Definition: effects.c:249
bool array_of_pointers_type_p(type)
Definition: type.c:3025
bool array_of_struct_type_p(type)
Definition: type.c:3133
#define type_struct(x)
Definition: ri.h:2964

References array_of_pointers_type_p(), array_of_struct_type_p(), array_type_p(), basic_derived, CELL, CONS, copy_cell(), ENTITY, entity_basic_concrete_type(), entity_type, f(), FOREACH, free_cell(), NIL, pointer_type_p(), points_to_cell_add_field_dimension(), points_to_cell_add_unbounded_subscripts(), points_to_cell_to_type(), recursive_cell_to_pointer_cells(), struct_type_p(), type_struct, type_variable, and variable_basic.

Referenced by cell_to_pointer_cells(), points_to_binding_arguments(), and recursive_cell_to_pointer_cells().

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

◆ recursive_store_independent_points_to_reference_p()

bool recursive_store_independent_points_to_reference_p ( type  t,
list  sl 
)
Parameters
tany type, but here initial reference type
slremaining subscript list, all subscripts are supposed to be store independent
Returns
true none of the subsequence subscript implies a dereferencing

Reduce the length of the subscript list

There are indices because of the first test on the number of subscripts

Parameters
sll

Definition at line 1169 of file points_to.c.

1169  {
1170  bool independent_p = false;
1171 
1172  if(ENDP(sl))
1173  independent_p = true;
1174  else if(struct_type_p(t)) {
1175  expression se = EXPRESSION(CAR(sl));
1179  independent_p = recursive_store_independent_points_to_reference_p(nt, CDR(sl));
1180  }
1181  else if(array_type_p(t)) {
1182  unsigned int d = array_type_dimension(t);
1183  if(gen_length(sl)<=d)
1184  independent_p = true;
1185  else {
1187  list nsl = sl;
1188  unsigned int i;
1189  // Skip the array subscripts
1190  for(i=0;i<d;i++)
1191  nsl = CDR(nsl);
1192  independent_p = recursive_store_independent_points_to_reference_p(nt, nsl);
1193  }
1194  }
1195  else if(pointer_type_p(t)) {
1196  /* There are indices because of the first test on the number of subscripts */
1197  independent_p = false;
1198  }
1199  else {
1200  // FI: It is more difficult... and it must have been programmed
1201  // somewhere else.
1202  pips_internal_error("Not implemented yet");
1203  }
1204 
1205  return independent_p;
1206 }
bool recursive_store_independent_points_to_reference_p(type t, list sl)
Definition: points_to.c:1169

References array_type_dimension(), array_type_p(), array_type_to_element_type(), CAR, CDR, ENDP, entity_basic_concrete_type(), EXPRESSION, expression_reference(), f(), gen_length(), pips_internal_error, pointer_type_p(), recursive_store_independent_points_to_reference_p(), reference_variable, and struct_type_p().

Referenced by recursive_store_independent_points_to_reference_p(), and store_independent_points_to_reference_p().

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

◆ reference_add_field_dimension()

reference reference_add_field_dimension ( reference  r,
entity  f 
)

add a field f as a subscript to a reference r if it is meaningful.

Leave r unchanged if not.

This function cannot be located in ri-util because it does need to know about abstract locations.

This does not build a standard reference, but a reference used within effects computation. Field accesses are replaced by subscripts.

Note that the reference generated may contain extra 0 subscripts to make it scalar...

No fields can be added to some special abstract locations.

FI: a problem due to typedefs apparently

Take care of special cases

Nothing done when the heap is modeled by a unique entity

This kind of entity cannot support a concrete access path but the type must be updated according to the field "f"

FI: This piece of code should be useless because the all_heap_locations entity is used only when ALIASING_ACROSS_TYPES is true.

Definition at line 1475 of file effects.c.

1476 {
1477  entity v = reference_variable(r);
1478 
1479  /* No fields can be added to some special abstract locations. */
1485  || entity_all_heap_locations_p(v) // Not typed, hopefully...
1486  )) {
1487  bool to_be_freed = false;
1488  type t = points_to_reference_to_type(r, &to_be_freed);
1489  //type t = ultimate_type(entity_type(v));
1491 
1492  if(struct_type_p(ut)) {
1494  type st = ultimate_type(entity_type(ste)); // FI: should be concrete_basic_type
1495  list fl = list_undefined;
1496  /* FI: a problem due to typedefs apparently */
1497  if(type_struct_p(st))
1498  fl = type_struct(st);
1499  else if(struct_type_p(st)) {
1501  type nst = ultimate_type(entity_type(nste));
1502  fl = type_struct(nst);
1503  }
1504  else
1505  pips_internal_error("Misunderstanding of struct typing.\n");
1506  entity nf = find_field_in_field_list(f, fl);
1507  if(!entity_undefined_p(nf)) {
1510  CONS(EXPRESSION, s, NIL));
1511  // FI: in case the field is an array
1513  }
1514  else {
1515  entity v = reference_variable(r);
1516  pips_internal_error("No field \"%s\" (\"%s\") for struct \"%s\"(\"%s\")\n",
1518  }
1519  }
1520  else {
1521  /* Take care of special cases */
1524  /* Nothing done when the heap is modeled by a unique entity */
1525  ; // FI: could be useful for unions as well
1526  }
1527  else if(array_of_struct_type_p(ut)) {
1528  extern bool get_int_property(const char *);
1529  bool strict_p = get_bool_property("POINTS_TO_STRICT_POINTER_TYPES");
1530  if(!strict_p) {
1531  // An implicit 0 subscript should be added
1533  // FI: This should be guarded as for the other structures
1534  // Some code should be factorized out
1536  pips_assert("No indices yet.\n", ENDP(reference_indices(r)));
1538  }
1539  }
1542  pips_assert("No indices yet.\n", ENDP(reference_indices(r)));
1544  }
1545  else
1546  pips_internal_error("Attempt at adding a field to an object that is not"
1547  " a struct.\n");
1548  }
1549  if(to_be_freed) free_type(t);
1550  }
1552  || entity_all_heap_locations_p(v) // Not typed, hopefully...?
1553  ) {
1554  /* This kind of entity cannot support a concrete access path but
1555  * the type must be updated according to the field "f"
1556  */
1557  type nt = entity_type(f); // concrete/ultimate_type()?
1560  reference_variable(r) = ne;
1562  }
1563  else if(entity_all_heap_locations_p(v)
1564  && !get_bool_property("ALIASING_ACROSS_TYPES")) {
1565  /* FI: This piece of code should be useless because the
1566  all_heap_locations entity is used only when
1567  ALIASING_ACROSS_TYPES is true. */
1569  reference_variable(r) = ne;
1571  }
1572  }
1573 
1574  return r;
1575 }
int get_int_property(const string)
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
entity find_field_in_field_list(entity, list)
To deal with fields declared in different C files.
Definition: type.c:5401
#define type_struct_p(x)
Definition: ri.h:2962

References array_of_struct_type_p(), basic_derived, compute_basic_concrete_type(), CONS, ENDP, entity_all_heap_locations_p(), entity_all_heap_locations_typed(), entity_all_module_heap_locations_p(), entity_anywhere_locations_p(), entity_basic_concrete_type(), entity_name, entity_nowhere_locations_p(), entity_null_locations_p(), entity_to_expression(), entity_type, entity_typed_anywhere_locations(), entity_typed_anywhere_locations_p(), entity_typed_nowhere_locations_p(), entity_undefined_p, entity_user_name(), EXPRESSION, f(), find_field_in_field_list(), free_type(), gen_nconc(), get_bool_property(), get_int_property(), int_to_expression(), list_undefined, NIL, overloaded_type_p(), pips_assert, pips_internal_error, points_to_reference_to_type(), reference_add_zero_subscripts(), reference_indices, reference_variable, struct_type_p(), type_struct, type_struct_p, type_variable, ultimate_type(), and variable_basic.

Referenced by points_to_cell_add_field_dimension(), and struct_assignment_to_points_to().

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

◆ reference_typed_anywhere_locations_p()

bool reference_typed_anywhere_locations_p ( reference  r)

test if a reference is the bottom of the lattice

Definition at line 141 of file anywhere_abstract_locations.c.

142 {
143  entity e = reference_variable(r);
144  bool anywhere_p = entity_typed_anywhere_locations_p(e);
145  return anywhere_p;
146 }

References entity_typed_anywhere_locations_p(), and reference_variable.

Referenced by any_assign_to_transformer(), and cell_typed_anywhere_locations_p().

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

◆ reference_unbounded_indices_p()

bool reference_unbounded_indices_p ( reference  r)

This function should be at expression.c.

It already exist and is called reference_with_unbounded_indices_p() but includes two cases that should be disjoint: constant indices and unbounded ones.

Definition at line 1373 of file type.c.

1374 {
1375  list sel = reference_indices(r);
1376  bool unbounded_p = true;
1377 
1378  FOREACH(EXPRESSION, se, sel) {
1379  if(!unbounded_expression_p(se)) {
1380  unbounded_p = false;
1381  break;
1382  }
1383  }
1384  return unbounded_p;
1385 }

References EXPRESSION, FOREACH, reference_indices, and unbounded_expression_p().

Referenced by strict_constant_path_p().

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

◆ related_points_to_cell_in_list_p()

bool related_points_to_cell_in_list_p ( cell  c,
list  L 
)

Two cells are related if they are based on the same entity.

Definition at line 149 of file points_to.c.

150 {
151  bool found_p = false;
153  entity ec = reference_variable(rc);
154  FOREACH(CELL, lc, L) {
155  reference rlc = cell_any_reference(lc);
156  entity elc = reference_variable(rlc);
157  if(ec==elc) {
158  found_p =true;
159  break;
160  }
161  }
162  return found_p;
163 }

References CELL, cell_any_reference(), FOREACH, and reference_variable.

Referenced by filter_formal_context_according_to_actual_context(), freed_list_to_points_to(), new_filter_formal_context_according_to_actual_context(), and recursive_filter_formal_context_according_to_actual_context().

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

◆ related_points_to_cells_p()

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

Definition at line 165 of file points_to.c.

166 {
167  bool related_p = false;
168  reference rc1 = cell_any_reference(c1);
169  entity ec1 = reference_variable(rc1);
170  reference rc2 = cell_any_reference(c2);
171  entity ec2 = reference_variable(rc2);
172  related_p = (ec1==ec2);
173  return related_p;
174 }

References cell_any_reference(), and reference_variable.

Referenced by sink_to_sources(), and unreachable_points_to_cell_p().

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

◆ reset_pt_to_list()

◆ set_pt_to_list()

◆ similar_arc_in_points_to_set_p()

bool similar_arc_in_points_to_set_p ( points_to  spt,
set  in,
approximation pa 
)

See if an arc like "spt" exists in set "in", regardless of its approximation.

If yes, returns the approximation of the arc found in "in".

See also arc_in_points_to_set_p(), which requires full identity

Parameters
sptpt
inn
paa

Definition at line 929 of file points_to.c.

930 {
931  bool in_p = false;
932  cell spt_source = points_to_source(spt);
933  cell spt_sink = points_to_sink(spt);
934  SET_FOREACH(points_to, pt, in) {
935  if(points_to_cell_equal_p(spt_source, points_to_source(pt))
936  && points_to_cell_equal_p(spt_sink, points_to_sink(pt))) {
937  *pa = points_to_approximation(pt);
938  in_p = true;
939  break;
940  }
941  }
942  return in_p;
943 }
bool points_to_cell_equal_p(cell c1, cell c2)
Definition: points_to.c:916

References points_to_approximation, points_to_cell_equal_p(), points_to_sink, points_to_source, and SET_FOREACH.

Referenced by filter_formal_out_context_according_to_formal_in_context().

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

◆ simple_reference_add_field_dimension()

reference simple_reference_add_field_dimension ( reference  r,
entity  f 
)

Do not check anything, just add f as a last subscript.

See above

Definition at line 1581 of file effects.c.

1582 {
1585  CONS(EXPRESSION, s, NIL));
1586  return r;
1587 }

References CONS, entity_to_expression(), EXPRESSION, f(), gen_nconc(), NIL, and reference_indices.

Referenced by add_inter_or_intraprocedural_field_entities(), and struct_assignment_to_points_to().

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

◆ statement_has_a_module_formal_argument_write_effect_p()

bool statement_has_a_module_formal_argument_write_effect_p ( statement  s,
entity  module,
statement_mapping  effects_list_map 
)

Return true if the statement has a write effect on at least one of the argument (formal parameter) of the module.

Note that the return variable of a function is also considered here as a formal parameter.

Parameters
moduleodule
effects_list_mapffects_list_map

Definition at line 247 of file effects.c.

250 {
251  bool write_effect_on_a_module_argument_found = false;
252  list effects_list = (list) GET_STATEMENT_MAPPING(effects_list_map, s);
253 
254  FOREACH(EFFECT, an_effect, effects_list)
255  {
257 
258  if (action_write_p(effect_action(an_effect))
261  module))) {
262  write_effect_on_a_module_argument_found = true;
263  break;
264  }
265  }
266 
267  return write_effect_on_a_module_argument_found;
268 
269 }
static entity a_variable
#define GET_STATEMENT_MAPPING(map, stat)
Definition: newgen-local.h:49
struct cons * list
Definition: newgen_types.h:106
bool variable_is_a_module_formal_parameter_p(entity, entity)
Definition: variable.c:1547
bool variable_return_p(entity)
True if a variable is the pseudo-variable used to store value returned by a function:
Definition: variable.c:1522

References a_variable, action_write_p, EFFECT, effect_action, effect_any_reference, FOREACH, GET_STATEMENT_MAPPING, module, reference_variable, variable_is_a_module_formal_parameter_p(), and variable_return_p().

+ Here is the call graph for this function:

◆ std_file_cell_p()

bool std_file_cell_p ( cell  c)

Definition at line 524 of file effects.c.

525 {
526  return(std_file_entity_p(cell_entity(c)));
527 }
bool std_file_entity_p(entity e)
Definition: entity.c:1232

References cell_entity(), and std_file_entity_p().

+ Here is the call graph for this function:

◆ std_file_effect_p()

bool std_file_effect_p ( effect  e)

Definition at line 519 of file effects.c.

520 {
521  return(std_file_entity_p(effect_entity(e)));
522 }

References effect_entity(), and std_file_entity_p().

Referenced by create_step_regions(), do_check_isolate_statement_preconditions_on_call(), effects_to_dma(), and std_file_effects_p().

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

◆ std_file_effects_p()

bool std_file_effects_p ( list  effects)

Definition at line 529 of file effects.c.

530 {
531  FOREACH(EFFECT,eff,effects)
532  if(std_file_effect_p(eff)) return true;
533  return false;
534 }
bool std_file_effect_p(effect e)
Definition: effects.c:519

References EFFECT, FOREACH, and std_file_effect_p().

+ Here is the call graph for this function:

◆ store_effect_p()

bool store_effect_p ( effect  e)

Definition at line 1062 of file effects.c.

1063 {
1064  action a = effect_action(e);
1066  bool store_p = action_kind_store_p(ak);
1067 
1068  return store_p;
1069 }

References action_kind_store_p, action_read, action_read_p, action_write, and effect_action.

Referenced by add_conflicts(), add_values_for_simple_effects_of_statement(), array_must_fully_written_by_regions_p(), c_convex_effects_on_formal_parameter_backward_translation(), create_values_for_simple_effect(), cumul_and_update_effects_of_statement(), DistArraysEffects(), effect_may_read_or_write_memory_paths_from_entity_p(), effects_read_variable_p(), effects_write_p(), effects_write_variable_p(), find_effect_actions_for_entity(), generic_apply_effects_to_transformer(), generic_effects_maymust_read_or_write_scalar_entity_p(), get_written_entities(), invariant_expression_p(), kill_effects(), loop_flt(), loop_regions_normalize(), module_to_value_mappings(), no_other_effects_on_references(), prettyprint_dependence_graph(), project_regions_along_loop_index(), project_regions_along_parameters(), pure_function_p(), region_exact_projection_along_variable(), region_intersection(), region_sup_difference(), region_union(), regions_dynamic_elim(), regions_may_convex_hull(), regions_must_convex_hull(), regions_transformer_apply(), safe_effects_for_reductions(), simple_switch_old_to_new(), update_compatible_reduction(), update_reduction_under_effect(), vars_read_and_written(), written_effect_p(), written_effects_to_dist_arrays_p(), xml_Chain_Graph(), xml_Compute_and_Need(), xml_Region_Parameter(), xml_TaskParameter(), and xml_TaskParameters().

+ Here is the caller graph for this function:

◆ store_independent_effect_p()

bool store_independent_effect_p ( effect  eff)

Does this effect define the same set of memory locations regardless of the current (environment and) memory state?

This function works only for standard references, not for points-to references, but is partially extended to cope with one anywhere...

FI: I do not understand why pointers could be indexed in standard references.

Parameters
effff

Definition at line 636 of file effects.c.

637 {
638  bool independent_p = false;
639 
640  ifdebug(1) {
642  pips_assert("Effect eff is consistent", effect_consistent_p(eff));
643  pips_assert("The reference is consistent", reference_consistent_p(r));
644  }
645 
646  if(anywhere_effect_p(eff))
647  independent_p = true;
648  else {
650  entity v = reference_variable(r);
652 
653  if(pointer_type_p(t)) {
654  list inds = reference_indices(r);
655 
656  independent_p = ENDP(inds);
657  }
658  else {
659  pips_assert("The reference is consistent", reference_consistent_p(r));
660 
661  independent_p = reference_with_constant_indices_p(r);
662  }
663  }
664 
665  return independent_p;
666 }
bool reference_consistent_p(reference p)
Definition: ri.c:2056
bool reference_with_constant_indices_p(reference r)
Definition: expression.c:3022

References anywhere_effect_p(), effect_any_reference, effect_consistent_p(), ENDP, entity_basic_concrete_type(), ifdebug, pips_assert, pointer_type_p(), reference_consistent_p(), reference_indices, reference_variable, and reference_with_constant_indices_p().

Referenced by add_values_for_simple_effects_of_statement(), effect_interference(), and effects_interfere_p().

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

◆ store_independent_points_to_indices_p()

bool store_independent_points_to_indices_p ( list  sl)

check that the subscript list il is either empty or made of integers or fields or unbounded entity "*".

What would you do with a constant range ?

Parameters
sll

Definition at line 1301 of file points_to.c.

1302 {
1303  bool constant_p = true;
1304 
1305  FOREACH(EXPRESSION, se, sl) {
1307  syntax s = expression_syntax(se);
1308  if(syntax_reference_p(s)) {
1309  reference r = syntax_reference(s);
1311  if(!entity_field_p(f)) {
1312  constant_p = false;
1313  break;
1314  }
1315  }
1316  else if(syntax_call_p(s)) {
1317  call c = syntax_call(s);
1318  entity f = call_function(c);
1319  if(!unbounded_entity_p(f)) {
1320  constant_p = false;
1321  break;
1322  }
1323  }
1324  else {
1325  constant_p = false;
1326  break;
1327  }
1328  }
1329  }
1330  return constant_p;
1331 }
bool unbounded_entity_p(entity f)
Definition: expression.c:4323

References call_function, constant_p(), entity_field_p(), EXPRESSION, expression_syntax, extended_integer_constant_expression_p(), f(), FOREACH, reference_variable, syntax_call, syntax_call_p, syntax_reference, syntax_reference_p, and unbounded_entity_p().

Referenced by store_independent_points_to_reference_p().

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

◆ store_independent_points_to_reference_p()

bool store_independent_points_to_reference_p ( reference  r)

Functions for points-to references, the kind of references used in points-to cells.

Does this points-to reference define the same set of memory locations regardless of the current (environment and) memory state?

The reference indices can be used to encode fields in data structures and can be applied to pointers as offset.

The types associated to the reference and to prefixes of the index list change. So a pointer dereferencing can be hidden anywhere. For instance, a[i][2] can be:

  • a 2-D array element,
  • a[i]+2 if a[i] is a 1-D array of pointers,
  • a.i[2], the second element of a 1-D array embedded as field i in struct a,
  • a.i+2, if field i is a pointer embedded as field i in struct a,
  • &a[i][2][0]... if a is an array of dimension 3 or more

Remember that *p is equivalent and encoded as p[0].

To guarantee store independence, either

  • the list of indices is empty, which covers abstract locations such as anywhere, null, etc.

or

  • the list of indices is a list of integer constants and fields and none of the intermediate types that are still indexed are pointers unless a multidimensional array is used...

Beware of named types...

Definition at line 1247 of file points_to.c.

1248 {
1249  list il = reference_indices(r);
1250  bool independent_p = ENDP(il); // any variable is a constant address
1251 
1252  if(!independent_p) {
1254  independent_p = false; // at least one index is store-dependent
1255  else {
1256  entity v = reference_variable(r);
1258  if(type_functional_p(t))
1259  independent_p = true;
1260  else
1261  independent_p =
1263  }
1264  }
1265 
1266  return independent_p;
1267 }
bool store_independent_points_to_indices_p(list sl)
check that the subscript list il is either empty or made of integers or fields or unbounded entity "*...
Definition: points_to.c:1301

References ENDP, entity_basic_concrete_type(), recursive_store_independent_points_to_reference_p(), reference_indices, reference_variable, store_independent_points_to_indices_p(), and type_functional_p.

Referenced by analyzed_reference_p(), assign_rhs_to_reflhs_to_transformer(), consistent_points_to_arc_p(), and reference_to_address_entity().

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

◆ store_or_update_pt_to_list()

void store_or_update_pt_to_list ( statement  ,
points_to_list   
)

Referenced by fi_points_to_storage(), and points_to_storage().

+ Here is the caller graph for this function:

◆ store_pt_to_list()

void store_pt_to_list ( statement  ,
points_to_list   
)

◆ strict_constant_path_p()

bool strict_constant_path_p ( reference  r)

Definition at line 1407 of file type.c.

1408 {
1409  bool constant_path = false;
1410  entity v = reference_variable(r);
1411  list l_ind = reference_indices(r);
1412 
1413  // Test the different top and bottom area
1414  if (entity_all_locations_p(v)
1418  ) {
1419  constant_path = true;
1420  }
1423  ) {
1424  constant_path = true;
1425  }
1428  ) {
1429  constant_path = true;
1430  }
1433  ) {
1434  constant_path = true;
1435  }
1438  ) {
1439  constant_path = true;
1440  }
1441  else if (entity_abstract_location_p(v)) { // Maybe this test permit to eliminate the 4 test just before?
1442  constant_path = true;
1443  }
1444  // Test if it's the constant NULL
1445  else if (entity_null_locations_p(v)) {
1446  constant_path = true;
1447  }
1448  // Test if it's a formal parameter
1449  else if (entity_stub_sink_p(v)) {
1450  constant_path = true;
1451  }
1452  // Test if it's a heap element
1453  else if (heap_area_p(v)) {
1454  constant_path = true;
1455  }
1456  // Maybe not efficient enough, for array of struct or struct of array?
1457  // Test if it's a structure
1458  else if (struct_type_p(entity_type(v)) && !ENDP(l_ind)) {
1459  constant_path = true;
1460  }
1461  // Test if it's a array with only *
1462  else if (!ENDP(l_ind)) {
1463  // see reference_unbounded_indices_p
1464  constant_path = reference_unbounded_indices_p(r);
1465  }
1466 
1467  return constant_path;
1468 }
bool reference_unbounded_indices_p(reference r)
This function should be at expression.c.
Definition: type.c:1373
bool struct_type_p(type t)
Returns true if t is of type derived and if the derived type is a struct.
Definition: type.c:3121

References ENDP, entity_abstract_location_p(), entity_all_dynamic_locations_p(), entity_all_heap_locations_p(), entity_all_locations_p(), entity_all_module_dynamic_locations_p(), entity_all_module_heap_locations_p(), entity_all_module_locations_p(), entity_all_module_stack_locations_p(), entity_all_module_static_locations_p(), entity_all_stack_locations_p(), entity_all_static_locations_p(), entity_anywhere_locations_p(), entity_nowhere_locations_p(), entity_null_locations_p(), entity_stub_sink_p(), entity_type, entity_typed_anywhere_locations_p(), entity_typed_nowhere_locations_p(), heap_area_p(), reference_indices, reference_unbounded_indices_p(), reference_variable, and struct_type_p().

Referenced by can_be_constant_path_p().

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

◆ stub_entity_of_module_p()

bool stub_entity_of_module_p ( entity  s,
entity  m 
)

There are several ways to decide if entity "s" is local to "m": its module name, its belonging to the declarations of m, its storage,... Let's avoir string comparisons and list scans...

Definition at line 624 of file anywhere_abstract_locations.c.

625 {
626  bool stub_p = entity_stub_sink_p(s);
627  if(stub_p) {
628  /* There are several ways to decide if entity "s" is local to "m":
629  its module name, its belonging to the declarations of m, its
630  storage,... Let's avoir string comparisons and list scans... */
631  storage ss = entity_storage(s);
632  if(storage_ram_p(ss)) {
633  ram rss = storage_ram(ss);
634  entity f = ram_function(rss);
635  stub_p = m==f;
636  }
637  }
638  return stub_p;
639 }

References entity_storage, entity_stub_sink_p(), f(), ram_function, storage_ram, and storage_ram_p.

Referenced by clean_up_points_to_stubs(), compute_points_to_binded_set(), and generic_points_to_set_to_stub_cell_list().

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

◆ stub_points_to_cell_p()

bool stub_points_to_cell_p ( cell  c)

Definition at line 108 of file points_to.c.

109 {
110  bool formal_p = true;
112  entity v = reference_variable(r);
113  formal_p = entity_stub_sink_p(v); // FI: can be a source too
114  return formal_p;
115 }

References cell_any_reference(), entity_stub_sink_p(), and reference_variable.

Referenced by freeable_points_to_cells(), freed_list_to_points_to(), freed_pointer_to_points_to(), null_equal_condition_to_points_to(), and points_to_to_context_points_to().

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

◆ text_pointer_value()

text text_pointer_value ( cell_relation  pv)

text text_region(effect reg) input : a region output : a text consisting of several lines of commentaries, representing the region modifies : nothing

of string

PREFIX

REFERENCES

DESCRIPTOR

sorts in such a way that constraints with phi variables come first.

APPROXIMATION

CLOSE

Parameters
pvv

Definition at line 480 of file prettyprint.c.

481 {
482  text tpv = text_undefined;
483 
484  bool foresys = false;
485  string str_prefix = get_comment_continuation();
487  Psysteme sc;
488  list /* of string */ ls;
489 
491  {
492  ifdebug(1)
493  {
494  return make_text(CONS(SENTENCE,
496  strdup(concatenate(str_prefix,
497  "undefined pointer value\n",
498  NULL))),
499  NIL));
500  }
501  else
502  pips_user_warning("unexpected pointer value undefined\n");
503  }
504  else
505  tpv = make_text(NIL);
506 
507  cell first_c = cell_relation_first_cell(pv);
508  cell second_c = cell_relation_second_cell(pv);
509 
510  pips_assert("there should not be preference cells in pointer values (first) \n",
511  !cell_preference_p(first_c));
512  pips_assert("there should not be preference cells in pointer values (second) \n",
513  !cell_preference_p(second_c));
514 
515  pips_assert("gaps not handled yet (first)", !cell_gap_p(first_c));
516  pips_assert("gaps not handled yet (second)", !cell_gap_p(second_c));
517 
518  pips_assert("the first cell must have value_of interpretation\n",
520 
521 
522  reference first_r = cell_reference(first_c);
523  reference second_r = cell_reference(second_c);
526 
527  /* PREFIX
528  */
530  append(" ");
531 
532  /* REFERENCES */
533  ls = effect_words_reference(first_r);
534 
535  FOREACH(STRING, s, ls) {append(s);}
536  gen_free_string_list(ls); ls = NIL;
537 
538  append(" == ");
539 
540  ls = effect_words_reference(second_r);
542  append("&");
543 
544  FOREACH(STRING, s, ls) {append(s);}
545  gen_free_string_list(ls); ls = NIL;
546 
547  /* DESCRIPTOR */
548  /* sorts in such a way that constraints with phi variables come first.
549  */
550  if(!descriptor_none_p(d))
551  {
552  sc = sc_copy(descriptor_convex(d));
554  system_sorted_text_format(line_buffer, str_prefix, tpv, sc,
556  vect_contains_phi_p, foresys);
557  sc_rm(sc);
558  }
559 
560  /* APPROXIMATION */
561  append(approximation_may_p(ap) ? " (may);" : " (exact);");
562 
563  /* CLOSE */
564  close_current_line(line_buffer, tpv,str_prefix);
565 
566  return tpv;
567 }
sentence make_sentence(enum sentence_utype tag, void *val)
Definition: text.c:59
text make_text(list a)
Definition: text.c:107
int is_inferior_cell_descriptor_pvarval(Pvecteur *pvarval1, Pvecteur *pvarval2)
weight function for Pvecteur passed as argument to sc_lexicographic_sort in prettyprint functions inv...
Definition: compare.c:305
void system_sorted_text_format(string line, string prefix, text txt, Psysteme ps, string(*variable_name)(Variable), bool(*put_first)(Pvecteur), bool a_la_fortran)
lower level hook for regions.
#define cell_relation_second_address_of_p(cr)
const char * pips_region_user_name(entity ent)
char * pips_region_user_name(entity ent) output : the name of entity.
Definition: prettyprint.c:169
#define append(s)
Definition: prettyprint.c:472
bool vect_contains_phi_p(Pvecteur)
bool vect_contains_phi_p(Pvecteur v) input : a vector output : true if v contains a PHI variable,...
Definition: effects.c:1427
#define cell_relation_approximation(x)
Definition: effects.h:515
#define descriptor_convex(x)
Definition: effects.h:601
#define cell_relation_undefined_p(x)
Definition: effects.h:486
void gen_free_string_list(list ls)
Definition: list.c:564
string get_comment_sentinel()
Start a single line comment.
Definition: misc.c:154
string get_comment_continuation()
Start a single line comment with continuation (blank spaces)
Definition: misc.c:167
static int * line_buffer
le buffer contenant la ligne que l'on doit lire en avance pour se rendre compte qu'on a finit de lire...
Definition: reader.c:251
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
Psysteme sc_copy(Psysteme ps)
Psysteme sc_copy(Psysteme ps): duplication d'un systeme (allocation et copie complete des champs sans...
Definition: sc_alloc.c:230
void sc_lexicographic_sort(Psysteme sc, int(*compare)(Pvecteur *, Pvecteur *))
Minimize first the lexico-graphic weight of each constraint according to the comparison function "com...
Definition: sc_unaires.c:206
#define MAX_LINE_LENGTH
maximum length of a line when prettyprinting...
void close_current_line(string, text, string)
Definition: util.c:235
#define SENTENCE(x)
newgen_unformatted_domain_defined
Definition: text.h:36
#define text_undefined
Definition: text.h:91
@ is_sentence_formatted
Definition: text.h:57
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62

References append, approximation_may_p, cell_gap_p, cell_preference_p, cell_reference, cell_relation_approximation, cell_relation_descriptor, cell_relation_first_cell, cell_relation_first_value_of_p, cell_relation_second_address_of_p, cell_relation_second_cell, cell_relation_undefined_p, close_current_line(), concatenate(), CONS, descriptor_convex, descriptor_none_p, effect_words_reference(), FOREACH, gen_free_string_list(), get_comment_continuation(), get_comment_sentinel(), ifdebug, is_inferior_cell_descriptor_pvarval(), is_sentence_formatted, line_buffer, make_sentence(), make_text(), MAX_LINE_LENGTH, NIL, pips_assert, pips_region_user_name(), pips_user_warning, sc_copy(), sc_lexicographic_sort(), sc_rm(), SENTENCE, strdup(), STRING, system_sorted_text_format(), text_undefined, and vect_contains_phi_p().

Referenced by print_pointer_value(), and text_pointer_values().

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

◆ text_pointer_values()

text text_pointer_values ( list  lpv,
string  header 
)

in case of loose_prettyprint, at least one region to print?

GO: No redundant test anymore, see text_statement_array_regions

header first

Parameters
lpvpv
headereader

Definition at line 571 of file prettyprint.c.

572 {
573  text tpv = make_text(NIL);
574  /* in case of loose_prettyprint, at least one region to print? */
575  bool loose_p = get_bool_property("PRETTYPRINT_LOOSE");
576 
577  /* GO: No redundant test anymore, see text_statement_array_regions */
578  if (lpv != (list) HASH_UNDEFINED_VALUE && lpv != list_undefined)
579  {
580  /* header first */
582  string str_prefix = get_comment_continuation();
583  if (loose_p)
584  {
585  strcpy(line_buffer,"\n");
587  }
588  else
589  {
591  }
592  append(" ");
593  append(header);
594  if(ENDP(lpv))
595  append(" none\n");
596  else
597  append("\n");
600  strdup(line_buffer)));
601  gen_sort_list(lpv, (int (*)(const void *,const void *)) pointer_value_compare);
602  FOREACH(CELL_RELATION, pv, lpv)
603  {
605  }
606 
607  if (loose_p)
610  strdup("\n")));
611  }
612  return tpv;
613 }
int pointer_value_compare(cell_relation *ppv1, cell_relation *ppv2)
Compares two pointer values for sorting.
Definition: compare.c:255
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
#define MERGE_TEXTS(r, t)
#define ADD_SENTENCE_TO_TEXT(t, p)

References ADD_SENTENCE_TO_TEXT, append, CELL_RELATION, ENDP, FOREACH, gen_sort_list(), get_bool_property(), get_comment_continuation(), get_comment_sentinel(), HASH_UNDEFINED_VALUE, is_sentence_formatted, line_buffer, list_undefined, make_sentence(), make_text(), MAX_LINE_LENGTH, MERGE_TEXTS, NIL, pointer_value_compare(), strdup(), and text_pointer_value().

Referenced by generic_print_code_pv(), and text_pv().

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

◆ type_declaration_effect_p()

bool type_declaration_effect_p ( effect  e)

Definition at line 1080 of file effects.c.

1081 {
1082  action a = effect_action(e);
1084  bool decl_p = action_kind_type_declaration_p(ak);
1085 
1086  return decl_p;
1087 }

References action_kind_type_declaration_p, action_read, action_read_p, action_write, and effect_action.

◆ typed_anywhere_effect_p()

bool typed_anywhere_effect_p ( effect  e)

Is it a typed anywhere effect? ANYMMODULE:ANYWHERE_b0, 1, 2.

Definition at line 352 of file effects.c.

353 {
354  return generic_anywhere_effect_p(e, 1);
355 }

References generic_anywhere_effect_p().

+ Here is the call graph for this function:

◆ types_compatible_for_effects_interprocedural_translation_p()

bool types_compatible_for_effects_interprocedural_translation_p ( type  real_arg_t,
type  formal_arg_t 
)

tests if the actual argument type and the formal argument type are compatible with the current state of the interprocedural translation algorithms.

safe default result

Parameters
real_arg_teal_arg_t
formal_arg_tormal_arg_t

Definition at line 932 of file type.c.

933 {
934  bool result = false; /* safe default result */
935 
936  if (real_arg_t == formal_arg_t)
937  result = true;
938  else
939  {
940  type real_arg_ct = compute_basic_concrete_type(real_arg_t);
941  type formal_arg_ct = compute_basic_concrete_type(formal_arg_t);
942 
943  result =
945  (real_arg_ct, formal_arg_ct);
946 
947  free_type(real_arg_ct);
948  free_type(formal_arg_ct);
949  }
950 
951  return result;
952 }

References basic_concrete_types_compatible_for_effects_interprocedural_translation_p(), compute_basic_concrete_type(), and free_type().

Referenced by c_convex_effects_on_formal_parameter_backward_translation().

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

◆ undefined_pointer_value_cell_p()

◆ undefined_pointer_value_entity()

◆ undefined_pointer_value_entity_p()

bool undefined_pointer_value_entity_p ( entity  e)

◆ union_compatible_effects_p()

bool union_compatible_effects_p ( effect  ef1,
effect  ef2 
)

DO NOT USE ANYMORE: NOT COMPATIBLE WITH ABSTRACT LOCATIONS.

besides, I do not see the interest after having called effects_compatible_p. BC Check compatibility conditions for effect union

In general, you do not want to union a read and a write, but you might want to do so to generate the set of referenced elements, for instance to generate communications or to allocate memory

You do not want to union an effect on store with an effect on environment or type declaration

Here we know: at1==at2 and akt1==akt2

The code below could be further unified, but it would not make it easier to understand

Beware: that's not true anymore because of abstract locations

For environment and type declaration, the descriptor is useless for the time being

Parameters
ef1f1
ef2f2

Definition at line 1354 of file effects.c.

1355 {
1356  action a1 = effect_action(ef1);
1357  tag at1 = action_tag(a1);
1359  tag akt1 = action_kind_tag(ak1);
1360  entity e1 = effect_variable(ef1);
1361  descriptor d1 = effect_descriptor(ef1);
1362  action a2 = effect_action(ef2);
1363  tag at2 = action_tag(a2);
1365  tag akt2 = action_kind_tag(ak2);
1366  entity e2 = effect_variable(ef2);
1367  descriptor d2 = effect_descriptor(ef2);
1368  bool compatible_p = true;
1369 
1370  pips_assert("effect e1 is consistent", effect_consistent_p(ef1));
1371  pips_assert("effect e2 is consistent", effect_consistent_p(ef2));
1372 
1373  if(at1!=at2) {
1374  /* In general, you do not want to union a read and a write, but
1375  you might want to do so to generate the set of referenced
1376  elements, for instance to generate communications or to
1377  allocate memory */
1378  compatible_p = false;
1379  }
1380  else if(akt1!=akt2) {
1381  /* You do not want to union an effect on store with an effect on
1382  environment or type declaration */
1383  compatible_p = false;
1384  }
1385  else {
1386  /* Here we know: at1==at2 and akt1==akt2 */
1387  /* The code below could be further unified, but it would not make
1388  it easier to understand */
1389  if(akt1==is_action_kind_store) {
1390  if(e1!=e2) /* Beware: that's not true anymore because of abstract locations */
1391  compatible_p = false;
1392  else {
1393  tag dt1 = descriptor_tag(d1);
1394  tag dt2 = descriptor_tag(d2);
1395 
1396  if(dt1!=dt2)
1397  compatible_p = false;
1398  }
1399  }
1400  else {
1401  /* For environment and type declaration, the descriptor is
1402  useless for the time being */
1403  compatible_p = e1==e2;
1404  }
1405  }
1406 
1407  return compatible_p;
1408 }
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
#define descriptor_tag(x)
Definition: effects.h:595
@ is_action_kind_store
Definition: effects.h:237
int tag
TAG.
Definition: newgen_types.h:92

References action_kind_tag, action_tag, action_to_action_kind(), descriptor_tag, effect_action, effect_consistent_p(), effect_descriptor, effect_variable, is_action_kind_store, and pips_assert.

+ Here is the call graph for this function:

◆ update_pt_to_list()

void update_pt_to_list ( statement  ,
points_to_list   
)

◆ variable_to_abstract_location()

entity variable_to_abstract_location ( entity  v)

returns the smallest abstract locations containing the location of variable v.

This does not work for formal parameters or, if it works, the caller module is not known and the resulting abstract location is very large. A large abstract location is returned.

No idea to model return values... even though they are located in the stack in real world.

If v cannot be converted into an abstract location, either the function aborts or an undefined entity is returned.

NULL is an abstract location

Definition at line 675 of file anywhere_abstract_locations.c.

676 {
678 
680  al = v;
681  /* NULL is an abstract location */
682  else if(entity_null_locations_p(v))
683  al = v;
684  else if(entity_variable_p(v)
686  && !variable_return_p(v)) {
687  bool typed_p = !get_bool_property("ALIASING_ACROSS_TYPES");
688 
689  // Too simplistic
690  //al = FindOrCreateEntity(mn, ln);
691 
692  if(formal_parameter_p(v)) {
693  const char * ln = FORMAL_AREA_LOCAL_NAME;
695  storage s = entity_storage(v);
696  formal fs = storage_formal(s);
697  entity f = formal_function(fs);
698  if(typed_p) {
699  const char* fn = entity_local_name(f);
700  al = entity_all_module_xxx_locations_typed(fn, ln, uvt);
701  }
702  else
704  entity_kind(al)=ABSTRACT_LOCATION; // should it be a static/dynamic/stack/heap area too ? not according to static_area_p
705  }
706  else { // must be a standard variable, or a stub
707  storage s = entity_storage(v);
708  ram r = storage_ram(s);
709  entity f = ram_function(r);
710  entity a = ram_section(r);
711  //string mn = entity_local_name(f);
712  const char *ln = string_undefined;
714 
715  if(static_area_p(a))
717  else if(dynamic_area_p(a))
719  else if(stack_area_p(a))
721  else if(heap_area_p(a))
723  else if(formal_area_p(a))
725  else
726  pips_internal_error("Unexpected area\n");
727 
728  if(typed_p) {
729  const char* fn = entity_local_name(f);
730  al = entity_all_module_xxx_locations_typed(fn, ln, uvt);
731  }
732  else
734  entity_kind(al)=ABSTRACT_LOCATION; // should it be a static/dynamic/stack/heap area too ? not according to static_area_p
735  }
736  }
737  else
738  pips_internal_error("arg. not in definition domain");
739 
740  pips_assert("al is an abstract location entity",
742 
743  return al;
744 }
bool dummy_parameter_entity_p(entity p)
is p a dummy parameter?
Definition: entity.c:1941
#define storage_formal(x)
Definition: ri.h:2524
#define formal_function(x)
Definition: ri.h:1406

References ABSTRACT_LOCATION, dummy_parameter_entity_p(), DYNAMIC_AREA_LOCAL_NAME, dynamic_area_p(), entity_abstract_location_p(), entity_all_module_xxx_locations(), entity_all_module_xxx_locations_typed(), entity_basic_concrete_type(), entity_kind, entity_local_name(), entity_null_locations_p(), entity_storage, entity_undefined, entity_variable_p, f(), FORMAL_AREA_LOCAL_NAME, formal_area_p(), formal_function, formal_parameter_p(), get_bool_property(), HEAP_AREA_LOCAL_NAME, heap_area_p(), pips_assert, pips_internal_error, ram_function, ram_section, STACK_AREA_LOCAL_NAME, stack_area_p(), STATIC_AREA_LOCAL_NAME, static_area_p(), storage_formal, storage_ram, string_undefined, and variable_return_p().

Referenced by add_conflicts(), entities_maymust_conflict_p(), entity_locations_max(), opkill_may_name(), and opkill_must_name().

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

◆ vect_contains_phi_p()

bool vect_contains_phi_p ( Pvecteur  v)

bool vect_contains_phi_p(Pvecteur v) input : a vector output : true if v contains a PHI variable, false otherwise modifies : nothing

Definition at line 1427 of file effects.c.

1428 {
1429  for(; !VECTEUR_NUL_P(v); v = v->succ)
1430  if (variable_phi_p((entity) var_of(v)))
1431  return(true);
1432 
1433  return(false);
1434 }
struct Svecteur * succ
Definition: vecteur-local.h:92
#define VECTEUR_NUL_P(v)
#define var_of(varval)

References Svecteur::succ, var_of, variable_phi_p, and VECTEUR_NUL_P.

Referenced by constraints_nb_phi_eq(), eq_var_nophi_min_coeff(), eq_var_phi(), some_phi_variable(), text_pointer_value(), text_points_to_relation(), and text_region_no_action().

+ Here is the caller graph for this function:

◆ word_points_to()

list word_points_to ( points_to  pt)
Parameters
ptt

Definition at line 242 of file prettyprint.c.

243 {
244  list l2 = NIL, l1 = NIL, rlt1 = NIL;
245 
246  pips_assert("pt is defined", !points_to_undefined_p(pt));
248  cell c1 = points_to_source(pt);
249  cell c2 = points_to_sink(pt);
250  // FI->AM: check all your copy_xxxx(); you often copy a large object
251  // to obtain a small part of it
252  reference r1 = cell_to_reference(c1);
253  reference r2 = cell_to_reference(c2);
255  string l3 = "-MAY-";
256 
257  if (approximation_exact_p(rel))
258  l3 = "-Exact-";
260  l2 = words_fictious_reference(r2);
261  else
262  l2 = points_to_words_reference(r2);
263 
264  l1 = points_to_words_reference(r1);
265 
266  rlt1 = gen_nconc((CONS(STRING,strdup("("), NIL)),l1);
267  rlt1 = gen_nconc(rlt1,(CONS(STRING,strdup(","), NIL)));
268 
269  rlt1 = gen_nconc(rlt1, l2);
270  rlt1 = gen_nconc(rlt1,(CONS(STRING,strdup(","), NIL)));
271  rlt1 = gen_nconc(rlt1,(CONS(STRING,strdup(l3), NIL)));
272  rlt1 = gen_nconc(rlt1,(CONS(STRING,strdup(")"), NIL)));
273  return rlt1;
274 }
bool points_to_consistent_p(points_to p)
static bool variable_p(entity e)
lready exist in cprettyprint but in mode static.
Definition: prettyprint.c:207
list words_fictious_reference(reference obj)
To modelize the heap locations we manufacture fictious reference, that triggered a bug when it appear...
Definition: prettyprint.c:215
list points_to_words_reference(reference r)
Specific handling of references appearing in points_to.
Definition: prettyprint.c:232
#define points_to_undefined_p(x)

References approximation_exact_p, cell_to_reference(), CONS, gen_nconc(), NIL, pips_assert, points_to_approximation, points_to_consistent_p(), points_to_sink, points_to_source, points_to_undefined_p, points_to_words_reference(), reference_variable, strdup(), STRING, variable_p(), and words_fictious_reference().

Referenced by generic_reference_to_points_to_matching_list(), generic_transform_sink_cells_from_matching_list(), and words_points_to_list().

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

◆ words_fictious_reference()

list words_fictious_reference ( reference  obj)

To modelize the heap locations we manufacture fictious reference, that triggered a bug when it appears as an argument of entity_user_name().

Parameters
objbj

Definition at line 215 of file prettyprint.c.

216 {
217  list pc = NIL;
218  entity e = reference_variable(obj);
219  pc = CHAIN_SWORD(pc, entity_name(e));
220  return(pc);
221 }

References CHAIN_SWORD, entity_name, NIL, and reference_variable.

Referenced by word_points_to().

+ Here is the caller graph for this function:

◆ words_pointer_value()

list words_pointer_value ( cell_relation  pv)
Parameters
pvv

Definition at line 428 of file prettyprint.c.

429 {
430  cell first_c = cell_relation_first_cell(pv);
431  cell second_c = cell_relation_second_cell(pv);
432 
433  pips_assert("there should not be preference cells in pointer values (first) \n",
434  !cell_preference_p(first_c));
435  pips_assert("there should not be preference cells in pointer values (second) \n",
436  !cell_preference_p(second_c));
437 
438  pips_assert("gaps not handled yet (first)", !cell_gap_p(first_c));
439  pips_assert("gaps not handled yet (second)", !cell_gap_p(second_c));
440 
441  pips_assert("the first cell must have value_of interpretation\n",
443 
444  list w = NIL;
445 
446  reference first_r = cell_reference(first_c);
447  reference second_r = cell_reference(second_c);
449  pips_assert("approximation is not must\n", !approximation_exact_p(ap));
450 
451  w= gen_nconc(w, effect_words_reference(first_r));
452  w = CHAIN_SWORD(w," == ");
453  w= gen_nconc(w, effect_words_reference(second_r));
454  w = CHAIN_SWORD(w, approximation_may_p(ap) ? " (may)" : " (exact)" );
455  return (w);
456 }

References approximation_exact_p, approximation_may_p, cell_gap_p, cell_preference_p, cell_reference, cell_relation_approximation, cell_relation_first_cell, cell_relation_first_value_of_p, cell_relation_second_cell, CHAIN_SWORD, effect_words_reference(), gen_nconc(), NIL, and pips_assert.

+ Here is the call graph for this function:

◆ words_points_to_list()

list words_points_to_list ( string  ,
points_to_list   
)

Referenced by text_points_to().

+ Here is the caller graph for this function: