26 #include "pips_config.h"
220 fprintf(stderr,
"result_paths are:\n");
227 ?
"value of" :
"address of");
228 (*effect_prettyprint_func)(eff);
232 fprintf(stderr,
"result_path is undefined\n");
335 pips_debug(5,
"eliminating local variables\n");
418 pips_debug(1,
"entity %s basic concrete type %s %s\n",
422 bool free_rhs_exp =
false;
488 pips_debug(2,
"standard library internal hook\n");
493 pips_debug(2,
"compilation unit, ignoring value for the moment\n");
520 l_out = pv_res.
l_out;
566 l_out = pv_res.
l_out;
574 l_out = pv_res.
l_out;
619 #define PV_NB_MAX_ITER_FIX_POINT 3
626 list l_in_cur = l_in;
634 l_in_cur = pv_res.
l_out;
646 bool fix_point_reached =
false;
647 l_out = pv_res.
l_out;
650 pips_debug(3,
"fix point iteration number %d.\n", i+1);
657 fix_point_reached = (l_out == l_iter_in)
659 pips_debug(3,
"fix point %s reached\n", fix_point_reached?
"":
"not");
664 if (!fix_point_reached)
673 &pv_res_failed, ctxt);
674 l_out = pv_res_failed.
l_out;
704 bool fix_point_reached =
false;
708 pips_debug(3,
"fix point iteration number %d.\n", i);
716 l_in_cur = pv_res_cond.
l_out;
726 l_out = pv_res_cond.
l_out;
731 if (i!=1 || before_p)
740 fix_point_reached = (l_out == l_iter_in)
742 pips_debug(3,
"fix point %s reached\n", fix_point_reached?
"":
"not");
747 if (!fix_point_reached)
756 &pv_res_failed, ctxt);
757 l_out = pv_res_failed.
l_out;
769 l_in_cur = pv_res_cond.
l_out;
808 l_in_cur = pv_res_init.
l_out;
813 bool fix_point_reached =
false;
817 pips_debug(3,
"fix point iteration number %d.\n", i);
824 l_in_cur = pv_res_cond.
l_out;
832 l_in_cur = pv_res_incr.
l_out;
839 fix_point_reached = (l_out == l_iter_in)
841 pips_debug(3,
"fix point %s reached\n", fix_point_reached?
"":
"not");
846 if (!fix_point_reached)
855 &pv_res_failed, ctxt);
856 l_out = pv_res_failed.
l_out;
866 l_in_cur = pv_res_cond.
l_out;
896 pips_user_warning(
"Pointer analysis for unstructured part of code not yet fully implemented:\n"
897 "Consider restructuring your code\n");
934 pips_debug(1,
"begin for undefined expression, returning undefined pointer_value\n");
935 pv_res->
l_out = l_in;
981 pv_res->
l_out = l_in;
1002 pv_res->
l_out = l_in;
1021 pv_res->
l_out = l_in;
1066 l_cur = pv_res_cur.
l_out;
1082 bool to_be_freed =
false;
1106 l_cur = pv_res->
l_out;
1113 pv_res->
l_out = l_cur;
1166 pv_res->
l_out = l_in;
1171 pv_res->
l_out = l_in;
1211 pv_res->
l_out = l_in;
1255 bool declaration_p,
list l_in,
1267 list l_tmp = l_rhs_kind;
1277 bool anywhere_lhs_p =
false;
1283 pips_assert(
"we cannot have an anywhere lhs for a declaration\n", !declaration_p);
1285 anywhere_lhs_p =
true;
1296 pips_debug(3,
"anywhere lhs (from aliases)\n");
1297 anywhere_lhs_p =
true;
1333 pips_debug(3,
"may lhs effect, changing all aliased effects to may\n");
1369 (eff_alias, anywhere_eff, rhs_kind, l_in);
1384 (eff_alias, anywhere_eff, rhs_kind, l_in);
1400 list l_rhs_kind_tmp = l_rhs_kind;
1407 (eff_alias, rhs_eff, rhs_kind, l_in);
1409 POP(l_rhs_kind_tmp);
1428 pv_res->
l_out = l_out;
1445 list l_rhs_base_eff,
list l_rhs_base_kind,
1446 bool declaration_p,
list l_in,
1449 list l_in_cur = l_in;
1452 bool anywhere_lhs_p =
false;
1462 pips_assert(
"we cannot have an anywhere lhs for a declaration\n", !declaration_p);
1464 anywhere_lhs_p =
true;
1492 list l_lhs_tmp = l_lhs;
1493 while (!anywhere_lhs_p && !
ENDP(l_lhs_tmp))
1505 bool free_rhs_kind =
false;
1506 list l_rhs_base_kind_tmp = l_rhs_base_kind;
1516 bool to_be_freed =
false;
1521 pips_debug(5,
"not same lhs and rhs types generating anywhere rhs\n");
1524 free_rhs_kind =
true;
1530 list lhs_dims_tmp = lhs_dims;
1531 for(
size_t i = 0; i < lhs_base_nb_dim; i++,
POP(lhs_dims_tmp));
1538 (*effect_add_expression_dimension_func)(rhs_eff, dim);
1543 l_rhs_eff =
CONS(
EFFECT, rhs_eff, l_rhs_eff);
1545 POP(l_rhs_base_kind_tmp);
1554 if (l_out != l_in_cur)
1561 anywhere_lhs_p =
true;
1603 l_in_cur = rhs_pv_res.
l_out;
1606 l_in_cur = lhs_pv_res.
l_out;
1620 pv_res->
l_out = l_in_cur;
1630 declaration_p, l_in_cur,
1637 declaration_p, l_in_cur,
1687 bool to_be_freed =
false;
1698 string new_name = NULL;
1711 bool single_path =
true;
1720 single_path =
false;
1768 pips_debug(5,
"non-variable formal parameter target type -> anywhere\n");
1809 debug_on(
"POINTER_VALUES_DEBUG_LEVEL");
1842 debug_on(
"POINTER_VALUES_DEBUG_LEVEL");
1877 debug_on(
"POINTER_VALUES_DEBUG_LEVEL");
1879 pips_debug(1,
"considering program \"%s\" with main \"%s\"\n", prog_name,
1886 pips_assert(
"some modules in the program", nmodules>0);
1888 for(
int i=0; i<nmodules; i++)
cell make_cell_reference(reference _field_)
void free_effect(effect p)
cell_interpretation make_cell_interpretation_value_of(void)
cell_interpretation make_cell_interpretation_address_of(void)
cell_relations make_cell_relations(list a)
approximation make_approximation_exact(void)
approximation make_approximation_may(void)
effect make_effect(cell a1, action a2, approximation a3, descriptor a4)
effect copy_effect(effect p)
EFFECT.
descriptor make_descriptor_none(void)
void free_cell_interpretation(cell_interpretation p)
cell copy_cell(cell p)
CELL.
value make_value_unknown(void)
type make_type_variable(variable _field_)
basic copy_basic(basic p)
BASIC.
ram make_ram(entity a1, entity a2, intptr_t a3, list a4)
reference make_reference(entity a1, list a2)
dimension make_dimension(expression a1, expression a2, list a3)
variable make_variable(basic a1, list a2, list a3)
void free_expression(expression p)
void free_storage(storage p)
storage copy_storage(storage p)
STORAGE.
reference copy_reference(reference p)
REFERENCE.
storage make_storage_ram(ram _field_)
entity entity_all_locations()
eturn ANY_MODULE:ANYWHERE (the top of the lattice)
size_t gen_array_nitems(const gen_array_t a)
void * gen_array_item(const gen_array_t a, size_t i)
#define pips_debug_effects(level, message, l_eff)
#define pips_debug_effect(level, message, eff)
for debug
list generic_proper_effects_of_complex_address_expression(expression, list *, int)
void effects_to_may_effects(list)
effect make_anywhere_effect(action)
void effect_add_dereferencing_dimension(effect)
bool null_pointer_value_effect_p(effect)
effect(* reference_to_effect_func)(reference, action, bool)
bool undefined_pointer_value_effect_p(effect)
void effects_to_must_effects(list)
void effect_to_may_effect(effect)
void generic_effects_reset_all_methods(void)
list generic_effect_generate_all_accessible_paths_effects_with_level(effect, type, tag, bool, int, bool)
void simple_cell_reference_with_address_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
bool simple_cell_preceding_p(cell, descriptor, cell, descriptor, transformer, bool, bool *)
string effect_to_string(effect)
void simple_cell_reference_with_value_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
void set_methods_for_simple_effects(void)
#define effect_may_p(eff)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define pips_debug_pv(level, message, pv)
#define effect_approximation_tag(eff)
#define make_reference_simple_effect(reference, action, approximation)
#define cell_relation_second_cell(cr)
#define pips_debug_pvs(level, message, l_pv)
#define cell_relation_second_value_of_p(cr)
#define cell_relation_first_cell(cr)
#define effect_exact_p(eff)
bool undefined_pointer_value_cell_p(cell)
type cell_to_type(cell, bool *)
void print_pointer_values(list)
entity null_pointer_value_entity(void)
action make_action_write_memory(void)
To ease the extension of action with action_kind.
cell make_null_pointer_value_cell(void)
cell_relation make_address_of_pointer_value(cell, cell, tag, descriptor)
type cell_reference_to_type(reference, bool *)
computes the type of a cell reference representing a memory access path.
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
cell make_undefined_pointer_value_cell(void)
action make_action_read_memory(void)
bool null_pointer_value_cell_p(cell)
entity undefined_pointer_value_entity(void)
pointer_values.c
#define cell_relations_list(x)
#define CELL_RELATION(x)
CELL_RELATION.
#define cell_undefined_p(x)
struct _newgen_struct_cell_relation_ * cell_relation
#define cell_interpretation_address_of_p(x)
struct _newgen_struct_statement_effects_ * statement_effects
#define cell_interpretation_value_of_p(x)
struct _newgen_struct_descriptor_ * descriptor
struct _newgen_struct_statement_cell_relations_ * statement_cell_relations
#define CELL_INTERPRETATION(x)
CELL_INTERPRETATION.
const char * module_name(const char *s)
Return the module part of an entity name.
void gen_full_free_list(list l)
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
void reset_current_module_entity(void)
Reset the current module entity.
void reset_current_module_statement(void)
Reset the current module statement.
const char * get_current_module_name(void)
Get the name of the current module.
statement set_current_module_statement(statement)
Set the current module statement.
statement get_current_module_statement(void)
Get the current module statement.
entity set_current_module_entity(entity)
static.c
entity get_current_module_entity(void)
Get the entity of the current module.
#define ENDP(l)
Test if a list is empty.
#define POP(l)
Modify a list pointer to point on the next element of the list.
#define NIL
The empty list (nil in Lisp)
size_t gen_length(const list l)
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
#define CAR(pcons)
Get the value of the first element of a list.
void gen_free_list(list l)
free the spine of the list
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
list gen_full_copy_list(list l)
Copy a list structure with element copy.
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
gen_array_t db_get_module_list(void)
Get an array of all the modules (functions, procedures and compilation units) of a workspace.
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
#define pips_user_warning
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
#define pips_internal_error
#define POINTER_DUMMY_TARGETS_AREA_LOCAL_NAME
#define MODULE_SEP_STRING
string bool_to_string(bool)
string concatenate(const char *,...)
Return the concatenation of the given strings.
#define GENERIC_GLOBAL_FUNCTION(name, type)
#define same_string_p(s1, s2)
void * stack_head(const stack)
returns the item on top of stack s
void stack_push(void *, stack)
stack use
stack stack_make(int, int, int)
allocation
void * stack_pop(stack)
POPs one item from stack s.
int bool
we cannot use an enum or stdbool because we need to be compatible with newgen, thus boolean need to h...
string get_main_entity_name(void)
Return the local name of the main module if it is available, or the local name of any module by defau...
#define pips_debug_pv_results(level, message, pv_res)
void pointer_values_remove_var(entity, bool, list, pv_results *, pv_context *)
void update_pv(statement, cell_relations)
list kill_pointer_values(list, list, pv_context *)
eliminate the cells of l_kill from l_in
void intrinsic_to_post_pv(entity, list, list, pv_results *, pv_context *)
pointer_values_intrinsics.c
list pvs_composition_with_transformer(list, transformer, pv_context *)
list simple_pvs_may_union(list, list)
list effect_find_aliased_paths_with_pointer_values(effect, list, pv_context *)
find all paths equivalent to eff cell in l_pv by performing a transitive closure
list simple_pvs_must_union(list, list)
bool simple_pvs_syntactically_equal_p(list, list)
void store_pv(statement, cell_relations)
cell_relation simple_pv_composition_with_transformer(cell_relation, transformer)
list make_simple_pv_from_simple_effects(effect, effect, cell_interpretation, list)
pointer_values_operators.c
statement_cell_relations get_pv(void)
bool bound_pv_p(statement)
static list sequence_to_post_pv(sequence seq, list l_in, pv_context *ctxt)
static void generic_module_initial_pointer_values(char *module_name, pv_context *ctxt)
static list instruction_to_post_pv(instruction inst, list l_in, pv_context *ctxt)
static list loop_to_post_pv(loop l, list l_in, pv_context *ctxt)
pv_results make_pv_results()
bool program_simple_pointer_values(const string prog_name)
list db_get_in_simple_pv(const char *module_name)
void db_put_in_simple_pv(const char *module_name, list l_pv)
bool simple_pointer_values(const string module_name)
interface to compute the simple pointer values of a given module
static list test_to_post_pv(test t, list l_in, pv_context *ctxt)
statement_cell_relations(* statement_cell_relations_function)()
bool initial_simple_pointer_values(const string module_name)
static list whileloop_to_post_pv(whileloop l, list l_in, pv_context *ctxt)
descriptor(* descriptor_function)()
void range_to_post_pv(range r, list l_in, pv_results *pv_res, pv_context *ctxt)
list db_get_program_simple_pv()
statement_cell_relations db_get_simple_pv(const char *module_name)
I don't know how to deal with these mappings if we have to analyse several modules at the same time w...
pv_context make_simple_pv_context()
static list module_initial_parameter_pv()
static list declarations_to_post_pv(list l_decl, list l_in, pv_context *ctxt)
#define PV_NB_MAX_ITER_FIX_POINT
void expression_to_post_pv(expression exp, list l_in, pv_results *pv_res, pv_context *ctxt)
void free_pv_results_paths(pv_results *pv_res)
static void external_call_to_post_pv(call c, list l_in, pv_results *pv_res, pv_context *ctxt)
void single_pointer_assignment_to_post_pv(effect lhs_eff, list l_rhs_eff, list l_rhs_kind, bool declaration_p, list l_in, pv_results *pv_res, pv_context *ctxt)
static list unstructured_to_post_pv(unstructured u, list l_in, pv_context *ctxt)
static void call_to_post_pv(call c, list l_in, pv_results *pv_res, pv_context *ctxt)
void db_put_initial_simple_pv(const char *module_name, list l_pv)
void db_put_program_simple_pv(list l_pv)
statement pv_context_statement_head(pv_context *ctxt)
void db_put_simple_pv(const char *module_name, statement_cell_relations scr)
void print_pv_results(pv_results pv_res)
void db_put_out_simple_pv(const char *module_name, list l_pv)
static void generic_module_pointer_values(char *module_name, pv_context *ctxt)
generic interface to compute the pointer values of a given module
void multiple_pointer_assignment_to_post_pv(effect lhs_base_eff, type lhs_type, list l_rhs_base_eff, list l_rhs_base_kind, bool declaration_p, list l_in, pv_results *pv_res, pv_context *ctxt)
list make_anywhere_anywhere_pvs()
statement_effects(* statement_effects_function)()
list db_get_out_simple_pv(const char *module_name)
static list statement_to_post_pv(statement stmt, list l_in, pv_context *ctxt)
void reset_pv_context(pv_context *p_ctxt)
static list forloop_to_post_pv(forloop l, list l_in, pv_context *ctxt)
list db_get_initial_simple_pv(const char *module_name)
static void generic_program_pointer_values(char *prog_name, pv_context *ctxt)
void pv_context_statement_pop(pv_context *ctxt)
cell_relation(* cell_relation_function)()
static list declaration_to_post_pv(entity e, list l_in, pv_context *ctxt)
void pv_context_statement_push(statement s, pv_context *ctxt)
void assignment_to_post_pv(expression lhs, bool may_lhs_p, expression rhs, bool declaration_p, list l_in, pv_results *pv_res, pv_context *ctxt)
string expression_to_string(expression e)
string string_of_type(const type)
void print_statement(statement)
Print a statement on stderr.
#define make_entity(n, t, s, i)
#define UNKNOWN_RAM_OFFSET
bool static_area_p(entity aire)
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
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...
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...
bool std_file_entity_p(entity e)
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
bool entity_main_module_p(entity e)
bool typedef_entity_p(entity e)
static int init
Maximal value set for Fortran 77.
const char * module_local_name(entity e)
Returns the module local user name.
entity std_file_entity_to_pointed_file_entity(entity e)
Dummy standard files targets.
expression make_address_of_expression(expression e)
generate a newly allocated expression for &(e)
expression make_unbounded_expression()
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
bool unbounded_expression_p(expression e)
list module_formal_parameters(entity func)
list module_formal_parameters(entity func) input : an entity representing a function.
bool compilation_unit_entity_p(entity e)
Check if the given module entity is a compilation unit.
bool entity_static_variable_p(entity)
return true if the entity is declared with the keyword static
type expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
bool type_fundamental_basic_p(type)
bool type_equal_p(type, type)
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
type pointed_type(type)
returns the type pointed by the input type if it is a pointer or an array of pointers
bool basic_concrete_type_leads_to_pointer_p(type)
returns true when the input type successors may be pointers
bool pointer_type_p(type)
Check for scalar pointers.
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...
bool variable_static_p(entity)
true if v appears in a SAVE statement, or in a DATA statement, or is declared static i C.
string type_to_string(const type)
type.c
#define type_functional_p(x)
#define transformer_undefined
#define functional_result(x)
#define value_constant(x)
#define syntax_reference(x)
#define forloop_initialization(x)
#define reference_variable(x)
#define control_predecessors(x)
#define forloop_increment(x)
#define instruction_loop(x)
#define type_functional(x)
#define whileloop_evaluation(x)
#define basic_pointer_p(x)
#define entity_storage(x)
#define statement_domain
newgen_sizeofexpression_domain_defined
#define type_statement_p(x)
@ is_syntax_sizeofexpression
#define range_increment(x)
#define EXPRESSION(x)
EXPRESSION.
#define cast_expression(x)
#define constant_int_p(x)
#define expression_undefined
@ is_instruction_unstructured
@ is_instruction_whileloop
@ is_instruction_expression
@ is_instruction_multitest
@ is_instruction_sequence
#define instruction_tag(x)
#define sequence_statements(x)
#define reference_indices(x)
#define instruction_sequence(x)
#define instruction_forloop(x)
#define control_successors(x)
#define unstructured_exit(x)
#define instruction_expression(x)
#define expression_undefined_p(x)
#define test_condition(x)
#define instruction_whileloop(x)
#define unstructured_entry(x)
#define variable_dimensions(x)
#define whileloop_body(x)
#define statement_declarations(x)
#define statement_instruction(x)
#define instruction_call(x)
#define forloop_condition(x)
#define call_arguments(x)
#define control_statement(x)
#define instruction_test(x)
#define whileloop_condition(x)
#define basic_string_p(x)
#define expression_syntax(x)
#define evaluation_before_p(x)
#define type_variable_p(x)
#define value_expression(x)
#define instruction_unstructured(x)
#define variable_basic(x)
#define STATEMENT(x)
STATEMENT.
#define entity_initial(x)
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
The structure used to build lists in NewGen.
pv_context is a structure holding the methods to use during pointer values analyses
void(* cell_reference_with_value_of_cell_reference_translation_func)(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
TRANSLATION OPERATORS.
bool(* cell_preceding_p_func)(cell, descriptor, cell, descriptor, transformer, bool, bool *)
COMPARISON OPERATORS.
list(* db_get_initial_pv_func)(const char *)
list(* pvs_must_union_func)(list, list)
BINARY OPERATORS.
list(* make_pv_from_effects_func)(effect, effect, cell_interpretation, list)
statement_cell_relations (*db_get_gen_pv_func)(char *);
list(* db_get_program_pv_func)()
void(* db_put_out_pv_func)(const char *, list)
void(* db_put_in_pv_func)(const char *, list)
void(* cell_reference_with_address_of_cell_reference_translation_func)(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
bool initial_pointer_values_p
ANALYSIS CONTROL.
void(* db_put_pv_func)(const char *, statement_cell_relations)
list(* pvs_may_union_func)(list, list)
list(* db_get_out_pv_func)(const char *)
list(* db_get_in_pv_func)(const char *)
statement_cell_relations(* db_get_pv_func)(const char *)
set to true for an initial module analysis
void(* db_put_initial_pv_func)(const char *, list)
bool(* pvs_equal_p_func)(list, list)
void(* db_put_program_pv_func)(list)
cell_relation(* pv_composition_with_transformer_func)(cell_relation, transformer)
UNARY OPERATORS.
pv_results is a structure holding the different results of an expression pointer values analysis
list result_paths_interpretations
resulting pointer path of the expression evaluation
list result_paths
resulting pointer_values
A gen_chunk is used to store every object.
#define exp
Avoid some warnings from "gcc -Wshadow".
list module_to_all_declarations(entity m)