PIPS
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "database.h"
#include "pipsdbm.h"
#include "resources.h"
#include "transformer.h"
#include "misc.h"
#include "properties.h"
#include "pipsmake.h"
#include "alias_private.h"
#include "instrumentation.h"
#include "ubs_private.h"
#include "effects-generic.h"
#include "effects-convex.h"
#include "effects-simple.h"
#include "conversion.h"
#include "text-util.h"
#include "alias-classes.h"
Go to the source code of this file.
Macros | |
#define | PREFIX1 "$UBS_CHECK" |
This analysis checks if the program uses a variable or an array element which has not been assigned a value. More... | |
#define | PREFIX2 "$UBS_CHECK_END" |
Variables | |
static FILE * | out |
static FILE * | out2 |
static entity | current_entity = entity_undefined |
static entity | current_mod = entity_undefined |
static statement | module_statement = statement_undefined |
static int | number_of_may_uninitialized_scalar_variables = 0 |
static int | number_of_may_uninitialized_array_variables = 0 |
static int | number_of_uninitialized_scalar_variables = 0 |
static int | number_of_uninitialized_array_variables = 0 |
static int | number_of_added_verifications = 0 |
static int | number_of_processed_modules = 0 |
static string | file_name |
static string | initialization_file |
static list | l_ubs_checks = NIL |
static list | l_initialized_commons = NIL |
#define PREFIX1 "$UBS_CHECK" |
This analysis checks if the program uses a variable or an array element which has not been assigned a value.
In this case, anything may happen: the program may appear to run normally, or may crash, or may behave unpredictably. We use IN regions that give a set of read variables not previously written. Depending on the nature of the variable: local, formal or global, we have different cases.
This is a top-down analysis that process a procedure before all its callees. Information given by callers is used to verify if we have to check for the formal parameters in the current module or not. In addition, we produce information in the resource MODULE.ubs to tell if the formal parameters of the called procedures have to be checked or not.
used_before_set > MODULE.ubs < PROGRAM.entities < MODULE.code < MODULE.in_regions < CALLERS.ubs Algorithm: take the list of IN regions of the module statement (attention, the IN region list contains the IN effect list and more exact, so always take the IN region list, although it is heavier) and check for each variable in this list. Case 1. Local variable a. if MUST IN at module statement, insert STOP 'Variable is used before set' b. else MAY IN at module statement,
(called procedure, common variable)
Some possible improvements: a.If V is a local variable/or common variable in module with no caller and 1.There is no WRITE on V in the current module => no need INITIALIZE + VERIFY, insert STOP before each MUST IN
2.If before a MUST IN on V, there is no WRITE on V => no need VERIFY, insert STOP before this MUST IN No no no, because we always VERIFY the formal variable => the actual variable may not be INITIALIZED => false We must have a mechanism to tell the called procedure if it have to insert a VERIFY or a STOP. But with some call paths : VERIFY, the others : STOP => what to do ? Safe way => INITIALIZE and VERIFY all.
By using IN regions, we can limit the number of variables to be checked, and code instrumentation is only used when we do not have enough information. Only array elements in the MAY IN regions are initialized, and array elements in the EXACT IN regions are verified, not the whole array.
do i_pips = k,l a(i_pips) = undef enddo
<A(PHI)-IN-MAY-{K<=PHI<=L}> DO I = M,N A(I) =I ENDDO
do i_pips = k,l if (a(i_pips) == undef) stop "used before set" enddo
<A(PHI)-IN-EXACT-{K<=PHI<=L}> DO I = K,L X(I) = A(I) ENDDO
There are two possible implementations :
Definition at line 149 of file used_before_set.c.
#define PREFIX2 "$UBS_CHECK_END" |
Definition at line 150 of file used_before_set.c.
Check if a common variable, i.e SUB1:COM1, declared in a common block BLOCK1 is visible in a module SUB2 or not
Definition at line 214 of file used_before_set.c.
References code_declarations, ENTITY, entity_initial, entity_local_name(), entity_storage, MAP, ram_section, storage_ram, and value_code.
Referenced by initialize_and_verify_common_variable(), and verify_used_before_set_statement_flt().
|
static |
Definition at line 168 of file used_before_set.c.
References number_of_added_verifications, number_of_may_uninitialized_array_variables, number_of_may_uninitialized_scalar_variables, number_of_processed_modules, number_of_uninitialized_array_variables, number_of_uninitialized_scalar_variables, and user_log().
Referenced by used_before_set().
Definition at line 184 of file used_before_set.c.
References CONS, ENTITY, entity_to_expression(), EXPRESSION, gen_nconc(), MAP, and NIL.
Referenced by initialize_array_variable(), and verify_array_variable().
Check if ent has already been initialized by a BLOCK DATA subprogram. Check if ent can also be initialized by an EQUIVALENCE variable
ram_shared does not work so we use common layout
ent is not in the main module scope. Since there may be variables in different common blocks with the same name => it is safe to add CALL INITIALIZATION_COMMONNAME for each common block, then add in subroutine INITIALIZATION_COMMONNAME the common, type, parameter declaration + common variable initializations
TO BE IMPROVED, do not verify unvisible common variable
Definition at line 902 of file used_before_set.c.
References approximation_exact_p, area_layout, BLANK_COMMON_LOCAL_NAME, common_variable_in_module_scope_p(), CONS, current_entity, current_mod, entities_may_conflict_p(), ENTITY, entity_blockdata_p(), entity_in_list_p(), entity_module_name(), entity_name, entity_scalar_p(), entity_storage, entity_type, entity_undefined, file_name, fprintf(), gen_nconc(), ifdebug, initialization_file, insert_common_declaration(), insert_initialization(), l_initialized_commons, local_name_to_top_level_entity(), MAP, module_local_name(), NIL, number_of_uninitialized_array_variables, number_of_uninitialized_scalar_variables, out, out2, pips_debug, PREFIX1, PREFIX2, ram_section, region_approximation, storage_ram, type_area, user_log(), and verify_used_before_set_statement().
Referenced by used_before_set().
Check if ent has already been initialized by a DATA statement. There are 3 cases:
Local variable ent is in a DATA or SAVE statement (distinguish DATA vs SAVE ???)
test to rewrite
Definition at line 995 of file used_before_set.c.
References approximation_exact_p, current_entity, current_mod, entity_name, entity_scalar_p(), entity_undefined, file_name, fprintf(), initialized_by_equivalent_variable_p(), insert_initialization(), module_local_name(), number_of_uninitialized_array_variables, number_of_uninitialized_scalar_variables, out, pips_debug, PREFIX1, PREFIX2, region_approximation, user_log(), variable_static_p(), and verify_used_before_set_statement().
Referenced by used_before_set().
|
static |
This function generates code that initializes every array element in the array region to a special value.
We use the algorithm_row_echelon(initial system, list of variables to scan, return condition, returned enumeration system) to generate the nested loop.
The generated code will be like this: IF (condition) THEN DO PHI1 = low1,up1 DO PHI2 = low2,up2 A(PHI1,PHI2) = SNan ENDDO ENDDO ENDIF If bounds can not be computed from the region, we use bounds from the array declaration DO PHI1 = dec_low1,dec_up1 DO PHI2 = dec_low2,dec_up2 A(PHI1,PHI2) = SNan ENDDO ENDDO CURRENTLY: we cannot check if all lower/upper bounds can be generated for variables Phii from region => use bounds from array declarations ATTENTION: the initialization is expensive, it increases much execution time (number of array variables * size of arrays :-))
Attention, this analysis uses PHI entities, static variables of region => init_regions
The assumed-size case cannot happen, because formal variables are not initialized
Definition at line 386 of file used_before_set.c.
References DIVIDE_OPERATOR_NAME, entities_to_expressions2(), entity_declaration_sc(), entity_intrinsic(), entity_type, exp, fprint_statement(), gen_length(), make_assign_statement(), make_reference(), make_special_value(), out, phi_entities_list(), ref, reference_to_expression(), systeme_to_loop_nest(), type_variable, and variable_dimensions.
Referenced by insert_initialization().
|
static |
This function generates an assignment that initializes the scalar variable.
Definition at line 357 of file used_before_set.c.
References entity_to_expression(), fprint_statement(), make_assign_statement(), make_special_value(), and out.
Referenced by insert_initialization().
This is not true !!! We must follow the IN regions of the equivalent variables
Definition at line 233 of file used_before_set.c.
References entity_name, entity_storage, gen_length(), ifdebug, pips_debug, print_entities(), ram_shared, and storage_ram.
Referenced by initialize_and_verify_local_variable().
Definition at line 860 of file used_before_set.c.
References BLANK_COMMON_LOCAL_NAME, common_members_of_module(), ENDP, ENTITY, entity_module_name(), fprintf(), gen_free_list(), ifdebug, local_name_to_top_level_entity(), MAP, module_local_name(), out2, print_entities(), words_common_variable(), and words_to_string().
Referenced by initialize_and_verify_common_variable().
|
static |
Definition at line 888 of file used_before_set.c.
References entity_scalar_p(), initialize_array_variable(), initialize_scalar_variable(), number_of_may_uninitialized_array_variables, and number_of_may_uninitialized_scalar_variables.
Referenced by initialize_and_verify_common_variable(), and initialize_and_verify_local_variable().
|
static |
nteger
loat
ogical : false = 0, true = 1
verloaded
omplex
tring
Definition at line 272 of file used_before_set.c.
References basic_complex, basic_float, basic_tag, entity_basic(), expression_undefined, int_to_expression(), is_basic_complex, is_basic_float, is_basic_overloaded, is_basic_string, make_call_expression(), make_constant_entity(), MakeConstant(), NIL, pips_internal_error, and user_log().
Referenced by initialize_array_variable(), initialize_scalar_variable(), and make_test_condition().
|
static |
This function makes a test like X.EQ.100000 or id_nan(A(PHI1)) or ir_nan(A(I,B(J))
loat
omplex
Definition at line 314 of file used_before_set.c.
References basic_complex, basic_float, basic_tag, CONS, entity_basic(), eq_expression, exp, EXPRESSION, expression_undefined, is_basic_complex, is_basic_float, make_call_expression(), make_constant_entity(), make_special_value(), and NIL.
Referenced by verify_array_element(), verify_array_variable(), and verify_scalar_variable().
Definition at line 194 of file used_before_set.c.
References concatenate(), ENTITY, entity_local_name(), MAP, and strdup().
Referenced by verify_array_variable().
Definition at line 204 of file used_before_set.c.
References concatenate(), exp, EXPRESSION, expression_to_string(), MAP, and strdup().
Referenced by verify_array_element().
Project all init variables from the system ps, there are 2 cases :
Definition at line 250 of file used_before_set.c.
References Ssysteme::base, old_value_entity_p(), sc_empty_p(), sc_rn_p(), Svecteur::succ, VALUE_ONE, vect_add_elem(), VECTEUR_NUL_P, and vecteur_var.
Referenced by verify_array_variable().
bool used_before_set | ( | const char * | module_name | ) |
File instrument.out is used to store ubs checks
Set and get the current properties concerning regions
Get the code of the module
Get IN regions of the module
File xxx.database/Src/initialization.f contains all the initializations of global variables
Common variable in main program
Local variable in main program, but attention, IN regions contain also static variables of other modules !!!
Formal or common variable
Local variable
save to resource
module_name | odule_name |
Definition at line 1046 of file used_before_set.c.
References callees_callees, concatenate(), copy_ubs(), current_mod, db_get_current_workspace_directory(), db_get_directory_name_for_module(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, display_used_before_set_statistics(), entity_main_module_p(), entity_module_name(), entity_undefined, file_name, find_rule_by_resource(), formal_parameter_p(), fprintf(), free(), get_regions_properties(), ifdebug, initialization_file, initialize_and_verify_common_variable(), initialize_and_verify_local_variable(), IO_EFFECTS_PACKAGE_NAME, l_ubs_checks, load_statement_in_regions(), local_name_to_top_level_entity(), make_ubs(), MAP, module_name(), module_statement, NIL, number_of_processed_modules, out, out2, pips_basename(), pips_debug, pips_user_warning, PREFIX1, PREFIX2, print_inout_regions(), REGION, region_entity, regions_end(), regions_init(), reset_current_module_entity(), reset_current_module_statement(), reset_in_effects(), reset_ordering_to_statement(), rule_phase, safe_fclose(), safe_fopen(), same_string_p, set_bool_property(), set_current_module_entity(), set_current_module_statement(), set_in_effects(), set_ordering_to_statement(), strdup(), user_file, variable_in_common_p(), verify_formal_and_common_variables(), and WORKSPACE_SRC_SPACE.
|
static |
o help debugging, reinitialize the integer and real array elements by 0 in order to avoid so much propagated NaN or 1000000 values. By doing this, we cannot detect all uninitialized variables but it helps Corinne, with thousand lines of code
nsert the assignment after the PRINT statement
Definition at line 429 of file used_before_set.c.
References basic_tag, concatenate(), entity_basic(), entity_name, exp, expression_reference(), fprintf(), free(), get_bool_property(), ifdebug, insert_statement(), int_to_expression(), make_assign_statement(), make_block_statement(), make_print_statement(), make_stop_statement(), make_test(), make_test_condition(), NIL, pips_debug, print_expression(), print_list_of_expressions(), print_statement(), reference_indices, statement_undefined, strdup(), test_to_statement, and test_undefined.
Referenced by verify_used_before_set_expression().
This function generates code that verifies if all array elements in the array region are initialized or not.
We use the algorithm_row_echelon(initial system, list of variables to scan, return condition, returned enumeration system) to generate the nested loop.
The generated code will be like this: IF (condition) THEN DO PHI1 = low1,up1 DO PHI2 = low2,up2 IF (A(PHI1,PHI2).EQ.SNan) STOP "A is used before set" ENDDO ENDDO ENDIF
o help debugging, reinitialize the integer and real array elements by 0 in order to avoid so much propagated NaN or 1000000 values. By doing this, we cannot detect all uninitialized variables but it helps Corinne, with thousand lines of code
nsert the assignment after the PRINT statement
o simplify the test condition, we have to remove preconditions from regions
If no bound is found for a variable PHIi => it is not the case because the region is MUST => TO PROVE
Definition at line 484 of file used_before_set.c.
References algorithm_row_echelon(), basic_tag, concatenate(), DIVIDE_OPERATOR_NAME, entities_to_expressions2(), entity_basic(), entity_intrinsic(), entity_list_to_base(), entity_name, entity_type, exp, fprintf(), free(), gen_length(), generate_optional_if(), get_bool_property(), ifdebug, insert_statement(), int_to_expression(), make_assign_statement(), make_block_statement(), make_print_statement(), make_reference(), make_stop_statement(), make_test(), make_test_condition(), NIL, phi_entities_list(), pips_debug, print_list_of_entities(), print_region, print_statement(), ref, reference_to_expression(), region_system, remove_temporal_variables_from_system(), sc_find_equalities(), statement_undefined, strdup(), systeme_to_loop_nest(), test_to_statement, test_undefined, type_variable, and variable_dimensions.
Referenced by verify_used_before_set_statement_flt().
Definition at line 758 of file used_before_set.c.
References caller_name, current_entity, current_mod, db_get_memory_resource(), entities_may_conflict_p(), entity_name, entity_storage, entity_undefined, formal_offset, formal_parameter_p(), integer_constant_p(), MAP, offset, pips_debug, same_entity_p(), storage_formal, STRING, UBS_CHECK, ubs_check_module, ubs_check_variable, ubs_list, and verify_used_before_set_statement().
Referenced by used_before_set().
|
static |
o help debugging, reinitialize the integer and real variables by 0 in order to avoid so much propagated NaN or 1000000 values. By doing this, we cannot detect all uninitialized variables but it helps Corinne, with thousand lines of code
nsert the assignment after the PRINT statement
Definition at line 401 of file used_before_set.c.
References basic_tag, concatenate(), entity_basic(), entity_name, entity_to_expression(), free(), get_bool_property(), insert_statement(), int_to_expression(), make_assign_statement(), make_block_statement(), make_print_statement(), make_stop_statement(), make_test(), make_test_condition(), NIL, print_statement(), statement_undefined, strdup(), test_to_statement, and test_undefined.
Referenced by verify_used_before_set_expression(), and verify_used_before_set_statement_flt().
If c is a procedure call, we have to update UBS resource in order to check for the corresponding variables in the frame of the called procedure. There are two possibilities:
always add (called procedure,common variable) to ubs resource, although current_entity may not in the IN regions of the called procedure
The current statement is not a call to another routine, so an assignment, or a READ, a WRITE, ... We have go though the argument list and generate a verification for each read (= IN region) of the current entity. This is really a redundant work with region's computation :-( So may be it is better to keep the list of regions, not a convex hull.
Examples : A = C(J) + FOO(C(I)), X(A(I)) = A(J) + A(K) READ *, A(B(I)), A(B(J))
SO FOR THE MOMENT, I ONLY TREAT SOME FREQUENT CASES: assignment, WRITE
Definition at line 547 of file used_before_set.c.
References call_arguments, call_function, CONS, current_entity, entity_local_name(), entity_module_p(), exp, EXPRESSION, expression_to_reference_list(), fprintf(), gen_nconc(), ifdebug, l_ubs_checks, make_integer_constant_entity(), make_ubs_check(), MAP, NIL, print_expression(), print_expressions(), ref, REFERENCE, reference_variable, same_entity_p(), UBS_CHECK, variable_in_common_p(), and verify_used_before_set_expression().
Referenced by verify_used_before_set_expression(), and verify_used_before_set_statement_flt().
|
static |
xists ? MAY IN for a MUST IN?
Definition at line 619 of file used_before_set.c.
References current_entity, current_mod, entity_scalar_p(), exp, expression_syntax, file_name, fprintf(), ifdebug, is_syntax_call, is_syntax_range, is_syntax_reference, module_local_name(), number_of_added_verifications, ORDERING_NUMBER, ORDERING_STATEMENT, out, pips_internal_error, PREFIX1, PREFIX2, print_expression(), ref, reference_variable, same_entity_p(), statement_ordering, syntax_call, syntax_reference, syntax_tag, verify_array_element(), verify_scalar_variable(), and verify_used_before_set_call().
Referenced by verify_used_before_set_call(), and verify_used_before_set_statement_flt().
|
static |
Definition at line 750 of file used_before_set.c.
References gen_null(), gen_recurse, module_statement, statement_domain, and verify_used_before_set_statement_flt().
Referenced by initialize_and_verify_common_variable(), initialize_and_verify_local_variable(), and verify_formal_and_common_variables().
there are IN regions like IN-EXACT-{0==-1} !!!
MUST IN region and variable belonging to current module scope (local, formal and visible global variable)
MAY IN region or common variable not in current module scope If the current statement is elementary, we have to treat it, else, we continue to go down with gen_recurse
Definition at line 665 of file used_before_set.c.
References approximation_exact_p, common_variable_in_module_scope_p(), current_entity, current_mod, entity_name, entity_scalar_p(), file_name, fprintf(), ifdebug, instruction_tag, instruction_test, instruction_whileloop, is_instruction_call, is_instruction_loop, is_instruction_sequence, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, load_statement_in_regions(), MAP, module_local_name(), number_of_added_verifications, ORDERING_NUMBER, ORDERING_STATEMENT, out, pips_debug, PREFIX1, PREFIX2, print_inout_regions(), print_statement(), REGION, region_approximation, region_empty_p, region_entity, same_entity_p(), statement_call(), statement_instruction, statement_ordering, test_condition, variable_in_common_p(), verify_array_variable(), verify_scalar_variable(), verify_used_before_set_call(), verify_used_before_set_expression(), and whileloop_condition.
Referenced by verify_used_before_set_statement().
Definition at line 839 of file used_before_set.c.
References CAR, CDR, CHAIN_SWORD, DIMENSION, entity_local_name(), entity_type, gen_nconc(), MAPL, NIL, pl, type_variable, type_variable_p, variable_dimensions, and words_numerical_dimension().
Referenced by insert_common_declaration().
This function prints a common variable with its numerical size, because we do not want to generate the PARAMETER declarations PARAMETER (NX=50) COMMON W(5*NX) => COMMON W(250)
Definition at line 811 of file used_before_set.c.
References CHAIN_SWORD, dimension_lower, dimension_upper, EvalNormalized(), gen_nconc(), int2a(), NIL, NORMALIZE_EXPRESSION, and Words_Expression().
Referenced by words_common_variable().
|
static |
Definition at line 153 of file used_before_set.c.
Referenced by initialize_and_verify_common_variable(), initialize_and_verify_local_variable(), verify_formal_and_common_variables(), verify_used_before_set_call(), verify_used_before_set_expression(), and verify_used_before_set_statement_flt().
|
static |
Definition at line 154 of file used_before_set.c.
Referenced by initialize_and_verify_common_variable(), initialize_and_verify_local_variable(), used_before_set(), verify_formal_and_common_variables(), verify_used_before_set_expression(), and verify_used_before_set_statement_flt().
|
static |
Definition at line 163 of file used_before_set.c.
Referenced by actual_c_parser(), add_new_compilation_unit(), add_new_module_from_text(), ask_emacs_to_display_a_graph(), check_c_file_syntax(), check_fortran_syntax_before_pips(), check_input_file_syntax(), close_resource_file(), compile_a_pure_function(), compile_a_special_io_function(), csplit(), csplit_close_files(), dbll_stat_file(), dbll_stat_local_file(), dbll_stat_resource_file(), edit_notify(), f95split(), find_file_in_directories(), full_graph_of_calls(), generate_a_directory_menu(), generate_hpf_remapping_file(), get_new_tmp_file_name(), get_resource_file_name(), get_view_file(), gpips_display_graph_file_display(), gpips_display_plain_file(), gpips_file_view(), graph_of_calls(), handle_file_name(), handle_include_file(), hpfc_filter(), hpfc_generate_path_name_of_file_name(), hpfc_print_file(), initialize_and_verify_common_variable(), initialize_and_verify_local_variable(), initialize_tpips_history(), insert_check_alias_before_statement(), insert_flag_before_call_site(), insert_test_before_caller(), insert_test_before_statement(), load_meta_data(), notify_hpfc_file_view(), open_resource_file(), parse_instrumented_file(), pips_process_file(), print_code_with_comp_regions(), print_continuation_conditions(), process_user_file(), read_from_eole(), safe_unlink(), save_meta_data(), set_c_parser_current_input_file_name(), set_c_parser_current_user_input_file_name(), tpips_close(), used_before_set(), verify_used_before_set_expression(), verify_used_before_set_statement_flt(), wpips_display_graph_file_display(), wpips_display_plain_file(), wpips_display_WP65_file(), wpips_file_view(), write_an_attachment_file(), and write_to_eole().
|
static |
Definition at line 164 of file used_before_set.c.
Referenced by initialize_and_verify_common_variable(), and used_before_set().
Definition at line 166 of file used_before_set.c.
Referenced by initialize_and_verify_common_variable().
Definition at line 165 of file used_before_set.c.
Referenced by used_before_set(), and verify_used_before_set_call().
|
static |
Definition at line 155 of file used_before_set.c.
Referenced by used_before_set(), and verify_used_before_set_statement().
|
static |
Definition at line 161 of file used_before_set.c.
Referenced by display_used_before_set_statistics(), verify_used_before_set_expression(), and verify_used_before_set_statement_flt().
|
static |
Definition at line 157 of file used_before_set.c.
Referenced by display_used_before_set_statistics(), and insert_initialization().
|
static |
Definition at line 156 of file used_before_set.c.
Referenced by display_used_before_set_statistics(), and insert_initialization().
|
static |
Definition at line 162 of file used_before_set.c.
Referenced by display_used_before_set_statistics(), and used_before_set().
|
static |
Definition at line 160 of file used_before_set.c.
Referenced by display_used_before_set_statistics(), initialize_and_verify_common_variable(), and initialize_and_verify_local_variable().
|
static |
Definition at line 159 of file used_before_set.c.
Referenced by display_used_before_set_statistics(), initialize_and_verify_common_variable(), and initialize_and_verify_local_variable().
|
static |
Definition at line 151 of file used_before_set.c.
Referenced by initialize_and_verify_common_variable(), initialize_and_verify_local_variable(), initialize_array_variable(), initialize_scalar_variable(), used_before_set(), verify_used_before_set_expression(), and verify_used_before_set_statement_flt().
|
static |
Definition at line 152 of file used_before_set.c.
Referenced by boolean_intrinsic_call_condition_to_points_to(), initialize_and_verify_common_variable(), insert_common_declaration(), and used_before_set().