diff options
Diffstat (limited to 'gcc-4.4.0/gcc/coverage.c')
-rw-r--r-- | gcc-4.4.0/gcc/coverage.c | 221 |
1 files changed, 173 insertions, 48 deletions
diff --git a/gcc-4.4.0/gcc/coverage.c b/gcc-4.4.0/gcc/coverage.c index 80c677d26..393246c84 100644 --- a/gcc-4.4.0/gcc/coverage.c +++ b/gcc-4.4.0/gcc/coverage.c @@ -151,7 +151,7 @@ static tree build_ctr_info_type (void); static tree build_ctr_info_value (unsigned, tree); static tree build_gcov_info (void); static void create_coverage (void); -static void get_da_file_name (const char *); +static char * get_da_file_name (const char *); static char * xstrdup_mask_random (const char *); /* Return the type node for gcov_type. */ @@ -232,6 +232,70 @@ is_last_module (unsigned mod_id) return (mod_id == module_infos[num_in_fnames - 1]->ident); } +/* Returns true if the command-line arguments stored in the given module-infos + are incompatible. */ +static bool +incompatible_cl_args (struct gcov_module_info* mod_info1, + struct gcov_module_info* mod_info2) +{ + char **warning_opts1 = XNEWVEC (char *, mod_info1->num_cl_args); + char **warning_opts2 = XNEWVEC (char *, mod_info2->num_cl_args); + char **non_warning_opts1 = XNEWVEC (char *, mod_info1->num_cl_args); + char **non_warning_opts2 = XNEWVEC (char *, mod_info2->num_cl_args); + unsigned int i, num_warning_opts1 = 0, num_warning_opts2 = 0; + unsigned int num_non_warning_opts1 = 0, num_non_warning_opts2 = 0; + bool warning_mismatch = false; + bool non_warning_mismatch = false; + unsigned int start_index1 = mod_info1->num_quote_paths + + mod_info1->num_bracket_paths + mod_info1->num_cpp_defines; + unsigned int start_index2 = mod_info2->num_quote_paths + + mod_info2->num_bracket_paths + mod_info2->num_cpp_defines; + + /* First, separate the warning and non-warning options. */ + for (i = 0; i < mod_info1->num_cl_args; i++) + if (mod_info1->string_array[start_index1 + i][1] == 'W') + warning_opts1[num_warning_opts1++] = + mod_info1->string_array[start_index1 + i]; + else + non_warning_opts1[num_non_warning_opts1++] = + mod_info1->string_array[start_index1 + i]; + + for (i = 0; i < mod_info2->num_cl_args; i++) + if (mod_info2->string_array[start_index2 + i][1] == 'W') + warning_opts2[num_warning_opts2++] = + mod_info2->string_array[start_index2 + i]; + else + non_warning_opts2[num_non_warning_opts2++] = + mod_info2->string_array[start_index2 + i]; + + /* Compare warning options. If these mismatch, we emit a warning. */ + if (num_warning_opts1 != num_warning_opts2) + warning_mismatch = true; + else + for (i = 0; i < num_warning_opts1 && !warning_mismatch; i++) + warning_mismatch = strcmp (warning_opts1[i], warning_opts2[i]) != 0; + + /* Compare non-warning options. If these mismatch, we emit a warning, and if + -fripa-disallow-opt-mismatch is supplied, the two modules are also + incompatible. */ + if (num_non_warning_opts1 != num_non_warning_opts2) + non_warning_mismatch = true; + else + for (i = 0; i < num_non_warning_opts1 && !non_warning_mismatch; i++) + non_warning_mismatch = + strcmp (non_warning_opts1[i], non_warning_opts2[i]) != 0; + + if (warn_ripa_opt_mismatch && (warning_mismatch || non_warning_mismatch)) + warning (OPT_Wripa_opt_mismatch, "command line arguments mismatch for %s " + "and %s", mod_info1->source_filename, mod_info2->source_filename); + + XDELETEVEC (warning_opts1); + XDELETEVEC (warning_opts2); + XDELETEVEC (non_warning_opts1); + XDELETEVEC (non_warning_opts2); + return flag_ripa_disallow_opt_mismatch && non_warning_mismatch; +} + /* Read in the counts file, if available. DA_FILE_NAME is the name of the gcda file, and MODULE_ID is the module id of the associated source module. */ @@ -239,6 +303,7 @@ is_last_module (unsigned mod_id) static void read_counts_file (const char *da_file_name, unsigned module_id) { + static int warned = 0; gcov_unsigned_t fn_ident = 0; char *name = NULL; counts_entry_t *summaried = NULL; @@ -255,15 +320,29 @@ read_counts_file (const char *da_file_name, unsigned module_id) if (!gcov_open (da_file_name, 1)) { + bool gcda_found = false; + if (PARAM_VALUE (PARAM_GCOV_DEBUG)) { /* Try to find .gcda file in the current working dir. */ da_file_name = lbasename (da_file_name); - if (!gcov_open (da_file_name, 1)) - return; + if (gcov_open (da_file_name, 1)) + { + gcda_found = true; + } } - else - return; + if (!gcda_found) + { + if (!warned) + { + warned = 1; + inform (input_location, + "file %s not found, disabling profile use", + da_file_name); + } + set_profile_use (false, false, true); + return; + } } if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC)) @@ -425,16 +504,16 @@ read_counts_file (const char *da_file_name, unsigned module_id) = (struct gcov_module_info *) alloca ((length + 2) * sizeof (gcov_unsigned_t)); gcov_read_module_info (mod_info, length); - module_infos_read++; - info_sz = (sizeof (struct gcov_module_info) + sizeof (void *) * (mod_info->num_quote_paths + mod_info->num_bracket_paths + - mod_info->num_cpp_defines)); + mod_info->num_cpp_defines + + mod_info->num_cl_args)); /* The first MODULE_INFO record must be for the primary module. */ - if (module_infos_read == 1) + if (module_infos_read == 0) { gcc_assert (mod_info->is_primary && !modset); + module_infos_read++; modset = pointer_set_create (); pointer_set_insert (modset, (void *)(size_t)mod_info->ident); primary_module_id = mod_info->ident; @@ -444,34 +523,50 @@ read_counts_file (const char *da_file_name, unsigned module_id) } else { + int fd; + char *aux_da_filename = get_da_file_name (mod_info->da_filename); gcc_assert (!mod_info->is_primary); - if (!pointer_set_insert (modset, (void *)(size_t)mod_info->ident) - /* Forbid mixed language LIPO for now. */ - && module_infos[0]->lang == mod_info->lang - /* Debugging support. */ - && module_infos_read <= max_group) + if (pointer_set_insert (modset, (void *)(size_t)mod_info->ident)) + inform (input_location, "Not importing %s: already imported", + mod_info->source_filename); + else if (module_infos[0]->lang != mod_info->lang) + inform (input_location, "Not importing %s: source language" + " different from primary module's source language", + mod_info->source_filename); + else if (module_infos_read == max_group) + inform (input_location, "Not importing %s: maximum group size" + " reached", mod_info->source_filename); + else if (incompatible_cl_args (module_infos[0], mod_info)) + inform (input_location, "Not importing %s: command-line" + " arguments not compatible with primary module", + mod_info->source_filename); + else if ((fd = open (aux_da_filename, O_RDONLY)) < 0) + inform (input_location, "Not importing %s: couldn't open %s", + mod_info->source_filename, aux_da_filename); + else { + close (fd); + module_infos_read++; add_input_filename (mod_info->source_filename); - module_infos = XRESIZEVEC (struct gcov_module_info *, module_infos, - num_in_fnames); - gcc_assert (num_in_fnames == module_infos_read); - module_infos[module_infos_read - 1] - = XCNEWVAR (struct gcov_module_info, info_sz); - memcpy (module_infos[module_infos_read - 1], mod_info, info_sz); + module_infos = XRESIZEVEC (struct gcov_module_info *, + module_infos, num_in_fnames); + gcc_assert (num_in_fnames == module_infos_read); + module_infos[module_infos_read - 1] + = XCNEWVAR (struct gcov_module_info, info_sz); + memcpy (module_infos[module_infos_read - 1], mod_info, + info_sz); } - else - module_infos_read--; } - /* Debugging */ - { - fprintf (stderr, - "MODULE Id=%d, Is_Primary=%s," - " Is_Exported=%s, Name=%s (%s)\n", - mod_info->ident, mod_info->is_primary?"yes":"no", - mod_info->is_exported?"yes":"no", mod_info->source_filename, - mod_info->da_filename); - } + if (flag_ripa_verbose) + { + inform (input_location, + "MODULE Id=%d, Is_Primary=%s," + " Is_Exported=%s, Name=%s (%s)", + mod_info->ident, mod_info->is_primary?"yes":"no", + mod_info->is_exported?"yes":"no", mod_info->source_filename, + mod_info->da_filename); + } } gcov_sync (offset, length); if ((is_error = gcov_is_error ())) @@ -514,7 +609,7 @@ get_coverage_counts_entry (struct function *func, elt.name = xstrdup_mask_random (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); entry = (counts_entry_t *) htab_find (counts_hash, &elt); - if (entry) + if (entry) return entry; if (!L_IPO_COMP_MODE) @@ -575,8 +670,9 @@ get_coverage_counts (unsigned counter, unsigned expected, unsigned cfg_checksum, if (!entry) { - warning (0, "no coverage for function %qs found", IDENTIFIER_POINTER - (DECL_ASSEMBLER_NAME (current_function_decl))); + if (!flag_dyn_ipa) + warning (0, "no coverage for function %qs found", IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (current_function_decl))); return NULL; } @@ -1292,6 +1388,29 @@ build_cpp_def_array_value (tree string_type, tree cpp_def_value, return cpp_def_value; } +/* Returns an array (tree) of command-line argument strings. STRING_TYPE is + the string type, CL_ARGS_VALUE is the initial value of the command-line + args array. */ + +static tree +build_cl_args_array_value (tree string_type, tree cl_args_value) +{ + unsigned int i; + for (i = 0; i < num_lipo_cl_args; i++) + { + int arg_length = strlen (lipo_cl_args[i]); + tree arg_string = build_string (arg_length + 1, lipo_cl_args[i]); + TREE_TYPE (arg_string) = + build_array_type (char_type_node, + build_index_type (build_int_cst (NULL_TREE, + arg_length))); + cl_args_value = tree_cons (NULL_TREE, + build1 (ADDR_EXPR, string_type, arg_string), + cl_args_value); + } + return cl_args_value; +} + /* Returns the value of the module info associated with the current source module being compiled. */ @@ -1408,11 +1527,19 @@ build_gcov_module_info_value (void) value = tree_cons (field, build_int_cstu (get_gcov_unsigned_t (), num_cpp_defines), value); + /* Num command-line args. */ + field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); + TREE_CHAIN (field) = fields; + fields = field; + value = tree_cons (field, build_int_cstu (get_gcov_unsigned_t (), + num_lipo_cl_args), value); + /* string array */ index_type = build_index_type (build_int_cst (NULL_TREE, num_quote_paths + num_bracket_paths + - num_cpp_defines)); + num_cpp_defines + + num_lipo_cl_args)); string_array_type = build_array_type (string_type, index_type); string_array = build_inc_path_array_value (string_type, string_array, quote_paths, num_quote_paths); @@ -1420,6 +1547,7 @@ build_gcov_module_info_value (void) bracket_paths, num_bracket_paths); string_array = build_cpp_def_array_value (string_type, string_array, cpp_defines_head); + string_array = build_cl_args_array_value (string_type, string_array); string_array = build_constructor_from_list (string_array_type, nreverse (string_array)); field = build_decl (FIELD_DECL, NULL_TREE, string_array_type); @@ -1645,9 +1773,10 @@ create_coverage (void) /* Get the da file name, given base file name. */ -void +static char * get_da_file_name (const char *base_file_name) { + char *da_file_name; int len = strlen (base_file_name); const char *prefix = profile_data_prefix; /* + 1 for extra '/', in case prefix doesn't end with /. */ @@ -1661,7 +1790,6 @@ get_da_file_name (const char *base_file_name) /* Name of da file. */ da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX) + prefix_len + 1); - da_base_file_name = XNEWVEC (char, len + 1); if (prefix) { @@ -1673,7 +1801,7 @@ get_da_file_name (const char *base_file_name) da_file_name[0] = 0; strcat (da_file_name, base_file_name); strcat (da_file_name, GCOV_DATA_SUFFIX); - strcpy (da_base_file_name, base_file_name); + return da_file_name; } /* Rebuild counts_hash already built the primary module. This hashtable @@ -1785,7 +1913,9 @@ coverage_init (const char *filename, const char* source_name) int src_name_prefix_len = 0; int len = strlen (filename); - get_da_file_name (filename); + da_file_name = get_da_file_name (filename); + da_base_file_name = XNEWVEC (char, strlen (filename) + 1); + strcpy (da_base_file_name, filename); /* Name of bbg file. */ bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1); @@ -1795,7 +1925,8 @@ coverage_init (const char *filename, const char* source_name) if (profile_data_prefix == 0 && !IS_ABSOLUTE_PATH (source_name)) { src_name_prefix = getpwd (); - src_name_prefix_len = strlen (src_name_prefix) + 1; + if (src_name_prefix) + src_name_prefix_len = strlen (src_name_prefix) + 1; } main_input_file_name = XNEWVEC (char, strlen (source_name) + 1 + src_name_prefix_len); @@ -1815,17 +1946,11 @@ coverage_init (const char *filename, const char* source_name) if (flag_profile_use && L_IPO_COMP_MODE) { unsigned i; - char *da_file_name_p = da_file_name; - char *da_base_file_name_p = da_base_file_name; gcc_assert (flag_dyn_ipa); rebuild_counts_hash (); for (i = 1; i < num_in_fnames; i++) - { - get_da_file_name (module_infos[i]->da_filename); - read_counts_file (da_file_name, module_infos[i]->ident); - } - da_file_name = da_file_name_p; - da_base_file_name = da_base_file_name_p; + read_counts_file (get_da_file_name (module_infos[i]->da_filename), + module_infos[i]->ident); } } |