diff options
Diffstat (limited to 'gcc/coverage.c')
-rw-r--r-- | gcc/coverage.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/gcc/coverage.c b/gcc/coverage.c index b1fce7d0e7..0a949c3a9f 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -1,5 +1,5 @@ /* Read and write coverage files, and associated functionality. - Copyright (C) 1990-2016 Free Software Foundation, Inc. + Copyright (C) 1990-2017 Free Software Foundation, Inc. Contributed by James E. Wilson, UC Berkeley/Cygnus Support; based on some ideas from Dain Samples of UC Berkeley. Further mangling by Bob Manson, Cygnus Support. @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "rtl.h" #include "tree.h" #include "tree-pass.h" +#include "memmodel.h" #include "tm_p.h" #include "stringpool.h" #include "cgraph.h" @@ -142,7 +143,8 @@ static void coverage_obj_finish (vec<constructor_elt, va_gc> *); tree get_gcov_type (void) { - machine_mode mode = smallest_mode_for_size (GCOV_TYPE_SIZE, MODE_INT); + machine_mode mode + = smallest_mode_for_size (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32, MODE_INT); return lang_hooks.types.type_for_mode (mode, false); } @@ -325,7 +327,9 @@ read_counts_file (void) gcov_sync (offset, length); if ((is_error = gcov_is_error ())) { - error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted", + error (is_error < 0 + ? G_("%qs has overflowed") + : G_("%qs is corrupted"), da_file_name); delete counts_hash; counts_hash = NULL; @@ -553,7 +557,8 @@ coverage_compute_lineno_checksum (void) = expand_location (DECL_SOURCE_LOCATION (current_function_decl)); unsigned chksum = xloc.line; - chksum = coverage_checksum_string (chksum, xloc.file); + if (xloc.file) + chksum = coverage_checksum_string (chksum, xloc.file); chksum = coverage_checksum_string (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); @@ -580,7 +585,8 @@ coverage_compute_profile_id (struct cgraph_node *n) bool use_name_only = (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID) == 0); chksum = (use_name_only ? 0 : xloc.line); - chksum = coverage_checksum_string (chksum, xloc.file); + if (xloc.file) + chksum = coverage_checksum_string (chksum, xloc.file); chksum = coverage_checksum_string (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl))); if (!use_name_only && first_global_object_name) @@ -751,7 +757,7 @@ build_var (tree fn_decl, tree type, int counter) TREE_STATIC (var) = 1; TREE_ADDRESSABLE (var) = 1; DECL_NONALIASED (var) = 1; - DECL_ALIGN (var) = TYPE_ALIGN (type); + SET_DECL_ALIGN (var, TYPE_ALIGN (type)); return var; } @@ -1053,7 +1059,34 @@ build_init_ctor (tree gcov_info_type) append_to_statement_list (stmt, &ctor); /* Generate a constructor to run it. */ - cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY); + int priority = SUPPORTS_INIT_PRIORITY + ? MAX_RESERVED_INIT_PRIORITY: DEFAULT_INIT_PRIORITY; + cgraph_build_static_cdtor ('I', ctor, priority); +} + +/* Generate the destructor function to call __gcov_exit. */ + +static void +build_gcov_exit_decl (void) +{ + tree init_fn = build_function_type_list (void_type_node, void_type_node, + NULL); + init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, + get_identifier ("__gcov_exit"), init_fn); + TREE_PUBLIC (init_fn) = 1; + DECL_EXTERNAL (init_fn) = 1; + DECL_ASSEMBLER_NAME (init_fn); + + /* Generate a call to __gcov_exit (). */ + tree dtor = NULL; + tree stmt = build_call_expr (init_fn, 0); + append_to_statement_list (stmt, &dtor); + + /* Generate a destructor to run it. */ + int priority = SUPPORTS_INIT_PRIORITY + ? MAX_RESERVED_INIT_PRIORITY: DEFAULT_INIT_PRIORITY; + + cgraph_build_static_cdtor ('D', dtor, priority); } /* Create the gcov_info types and object. Generate the constructor @@ -1111,6 +1144,7 @@ coverage_obj_init (void) DECL_NAME (gcov_info_var) = get_identifier (name_buf); build_init_ctor (gcov_info_type); + build_gcov_exit_decl (); return true; } |