From 35b6fdcfc2ea1cc14b04038dadae2a52792ea5eb Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Thu, 15 Jul 2004 17:33:01 +0000 Subject: [PATCH] * Fix for g++/15861 2004-07-15 Frank Ch. Eigler g++/15861 * cgraphunit.c (cgraph_build_static_cdtor): Add priority argument. * cgraph.h: Update declaration. * c-decl.c (build_cdtor): Update call with default priority. * coverage.c (create_coverage): Ditto. * tree-mudflap.c (mf_init_fndecl): New tree. (mudflap_init): Set it. (mudflap_register_call): Arrange to call __mf_init before the first __mf_register call. (mudflap_finish_file): Mark the mudflap static initializer as extra high priority, to beat all C++ static constructors. 2004-07-15 Frank Ch. Eigler g++/15861 * jcf-parse.c (java_emit_static_constructor): Specify default priority. From-SVN: r84760 --- gcc/ChangeLog | 14 ++++ gcc/c-decl.c | 2 +- gcc/cgraph.h | 2 +- gcc/cgraphunit.c | 4 +- gcc/coverage.c | 2 +- gcc/java/ChangeLog | 6 ++ gcc/java/jcf-parse.c | 2 +- gcc/tree-mudflap.c | 195 ++++++++++++++++++++++++------------------- 8 files changed, 133 insertions(+), 94 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d851a8286eb..8d4a911dcbd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2004-07-15 Frank Ch. Eigler + + g++/15861 + * cgraphunit.c (cgraph_build_static_cdtor): Add priority argument. + * cgraph.h: Update declaration. + * c-decl.c (build_cdtor): Update call with default priority. + * coverage.c (create_coverage): Ditto. + * tree-mudflap.c (mf_init_fndecl): New tree. + (mudflap_init): Set it. + (mudflap_register_call): Arrange to call __mf_init before the first + __mf_register call. + (mudflap_finish_file): Mark the mudflap static initializer as extra + high priority, to beat all C++ static constructors. + 2004-07-15 Jeff Law * loop.c (check_insn_for_givs): Restore check for code labels that was diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 6ff2dff081f..6414955a3d2 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -6616,7 +6616,7 @@ build_cdtor (int method_type, tree cdtors) append_to_statement_list (build_function_call (TREE_VALUE (cdtors), 0), &body); - cgraph_build_static_cdtor (method_type, body); + cgraph_build_static_cdtor (method_type, body, DEFAULT_INIT_PRIORITY); } /* Perform final processing on one file scope's declarations (or the diff --git a/gcc/cgraph.h b/gcc/cgraph.h index c91f6f87413..0c86b76962f 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -192,6 +192,6 @@ void verify_cgraph (void); void verify_cgraph_node (struct cgraph_node *); void cgraph_mark_inline_edge (struct cgraph_edge *e); void cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate); -void cgraph_build_static_cdtor (char which, tree body); +void cgraph_build_static_cdtor (char which, tree body, int priority); #endif /* GCC_CGRAPH_H */ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 39a4e32ef0e..79d5553aa9c 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1792,7 +1792,7 @@ cgraph_optimize (void) GENERIC statements. */ void -cgraph_build_static_cdtor (char which, tree body) +cgraph_build_static_cdtor (char which, tree body, int priority) { static int counter = 0; char which_buf[16]; @@ -1846,6 +1846,6 @@ cgraph_build_static_cdtor (char which, tree body) fn = targetm.asm_out.constructor; else fn = targetm.asm_out.destructor; - fn (XEXP (DECL_RTL (decl), 0), DEFAULT_INIT_PRIORITY); + fn (XEXP (DECL_RTL (decl), 0), priority); } } diff --git a/gcc/coverage.c b/gcc/coverage.c index 15a6a41873e..888d5cde2c3 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -939,7 +939,7 @@ create_coverage (void) append_to_statement_list (t, &body); /* Generate a constructor to run it. */ - cgraph_build_static_cdtor ('I', body); + cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY); } /* Perform file-level initialization. Read in data file, generate name diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index b111dad3ce7..76bef669f08 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,9 @@ +2004-07-15 Frank Ch. Eigler + + g++/15861 + * jcf-parse.c (java_emit_static_constructor): Specify default + priority. + 2004-07-13 Per Bothner * java-tree.h (all_class_filename): Remove useless macro. diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index 07f8ccc754b..5a0a87f9b19 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -887,7 +887,7 @@ java_emit_static_constructor (void) write_resource_constructor (&body); if (body) - cgraph_build_static_cdtor ('I', body); + cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY); } void diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c index 2320bc9f2d9..adfb3c7b771 100644 --- a/gcc/tree-mudflap.c +++ b/gcc/tree-mudflap.c @@ -268,6 +268,9 @@ static GTY (()) tree mf_register_fndecl; /* extern void __mf_unregister (void *ptr, size_t sz, int type); */ static GTY (()) tree mf_unregister_fndecl; +/* extern void __mf_init (); */ +static GTY (()) tree mf_init_fndecl; + /* Helper for mudflap_init: construct a decl with the given category, name, and type, mark it an external reference, and pushdecl it. */ static inline tree @@ -303,13 +306,15 @@ mf_make_mf_cache_struct_type (tree field_type) return struct_type; } -#define build_function_type_3(rtype, arg1, arg2, arg3) \ - build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2, \ - tree_cons (0, arg3, void_list_node)))) -#define build_function_type_4(rtype, arg1, arg2, arg3, arg4) \ - build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2, \ - tree_cons (0, arg3, tree_cons (0, arg4, \ - void_list_node))))) +#define build_function_type_0(rtype) \ + build_function_type (rtype, void_list_node) +#define build_function_type_3(rtype, arg1, arg2, arg3) \ + build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2, \ + tree_cons (0, arg3, void_list_node)))) +#define build_function_type_4(rtype, arg1, arg2, arg3, arg4) \ + build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2, \ + tree_cons (0, arg3, tree_cons (0, arg4, \ + void_list_node))))) /* Initialize the global tree nodes that correspond to mf-runtime.h declarations. */ @@ -321,42 +326,48 @@ mudflap_init (void) tree mf_cache_array_type; tree mf_check_register_fntype; tree mf_unregister_fntype; + tree mf_init_fntype; if (done) return; done = true; mf_uintptr_type = lang_hooks.types.type_for_mode (ptr_mode, - /*unsignedp=*/true); + /*unsignedp=*/true); mf_const_string_type = build_pointer_type (build_qualified_type - (char_type_node, TYPE_QUAL_CONST)); + (char_type_node, TYPE_QUAL_CONST)); mf_cache_struct_type = mf_make_mf_cache_struct_type (mf_uintptr_type); mf_cache_structptr_type = build_pointer_type (mf_cache_struct_type); mf_cache_array_type = build_array_type (mf_cache_struct_type, 0); mf_check_register_fntype = build_function_type_4 (void_type_node, ptr_type_node, size_type_node, - integer_type_node, mf_const_string_type); + integer_type_node, mf_const_string_type); mf_unregister_fntype = build_function_type_3 (void_type_node, ptr_type_node, size_type_node, - integer_type_node); + integer_type_node); + mf_init_fntype = + build_function_type_0 (void_type_node); mf_cache_array_decl = mf_make_builtin (VAR_DECL, "__mf_lookup_cache", - mf_cache_array_type); + mf_cache_array_type); mf_cache_shift_decl = mf_make_builtin (VAR_DECL, "__mf_lc_shift", - unsigned_char_type_node); + unsigned_char_type_node); mf_cache_mask_decl = mf_make_builtin (VAR_DECL, "__mf_lc_mask", - mf_uintptr_type); + mf_uintptr_type); mf_check_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_check", - mf_check_register_fntype); + mf_check_register_fntype); mf_register_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_register", - mf_check_register_fntype); + mf_check_register_fntype); mf_unregister_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_unregister", - mf_unregister_fntype); + mf_unregister_fntype); + mf_init_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_init", + mf_init_fntype); } #undef build_function_type_4 #undef build_function_type_3 +#undef build_function_type_0 /* ------------------------------------------------------------------------ */ @@ -446,7 +457,7 @@ mf_decl_clear_locals (void) static void mf_build_check_statement_for (tree addr, tree size, - block_stmt_iterator *instr_bsi, + block_stmt_iterator *instr_bsi, location_t *locus, tree dirflag) { tree_stmt_iterator head, tsi; @@ -536,13 +547,13 @@ mf_build_check_statement_for (tree addr, tree size, /* Quick validity check. if (__mf_elem->low > __mf_base - || (__mf_elem_high < __mf_base + sizeof(T) - 1)) - { - __mf_check (); - ... and only if single-threaded: - __mf_lookup_shift_1 = f...; - __mf_lookup_mask_l = ...; - } + || (__mf_elem_high < __mf_base + sizeof(T) - 1)) + { + __mf_check (); + ... and only if single-threaded: + __mf_lookup_shift_1 = f...; + __mf_lookup_mask_l = ...; + } It is expected that this body of code is rarely executed so we mark the edge to the THEN clause of the conditional jump as unlikely. */ @@ -556,8 +567,8 @@ mf_build_check_statement_for (tree addr, tree size, /* Construct '__mf_elem->high < __mf_base + sizeof(T) - 1'. First build: - 1) u <-- '__mf_elem->high' - 2) v <-- '__mf_base + sizeof (T) - 1'. + 1) u <-- '__mf_elem->high' + 2) v <-- '__mf_base + sizeof (T) - 1'. Then build 'u <-- (u < v). */ @@ -567,7 +578,7 @@ mf_build_check_statement_for (tree addr, tree size, TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE); v = convert (mf_uintptr_type, - size_binop (MINUS_EXPR, size, size_one_node)); + size_binop (MINUS_EXPR, size, size_one_node)); v = fold (build (PLUS_EXPR, mf_uintptr_type, mf_base, v)); u = build (LT_EXPR, boolean_type_node, u, v); @@ -584,8 +595,8 @@ mf_build_check_statement_for (tree addr, tree size, /* Build the conditional jump. 'cond' is just a temporary so we can simply build a void COND_EXPR. We do need labels in both arms though. */ t = build (COND_EXPR, void_type_node, cond, - build (GOTO_EXPR, void_type_node, tree_block_label (then_bb)), - build (GOTO_EXPR, void_type_node, tree_block_label (join_bb))); + build (GOTO_EXPR, void_type_node, tree_block_label (then_bb)), + build (GOTO_EXPR, void_type_node, tree_block_label (join_bb))); SET_EXPR_LOCUS (t, locus); tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING); @@ -593,7 +604,7 @@ mf_build_check_statement_for (tree addr, tree size, the conditional jump, if (__mf_elem->low > __mf_base - || (__mf_elem_high < __mf_base + sizeof(T) - 1)) + || (__mf_elem_high < __mf_base + sizeof(T) - 1)) The lowered GIMPLE tree representing this code is in the statement list starting at 'head'. @@ -612,9 +623,9 @@ mf_build_check_statement_for (tree addr, tree size, This is the body of the conditional. */ u = tree_cons (NULL_TREE, - mf_file_function_line_tree (locus == NULL ? UNKNOWN_LOCATION - : *locus), - NULL_TREE); + mf_file_function_line_tree (locus == NULL ? UNKNOWN_LOCATION + : *locus), + NULL_TREE); u = tree_cons (NULL_TREE, dirflag, u); u = tree_cons (NULL_TREE, size, u); u = tree_cons (NULL_TREE, mf_value, u); @@ -672,14 +683,14 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp, { tree dom = TYPE_DOMAIN (TREE_TYPE (op0)); - /* Test for index in range. Break if not. */ - if (!dom - || (! TYPE_MIN_VALUE (dom) - || ! really_constant_p (TYPE_MIN_VALUE (dom))) - || (! TYPE_MAX_VALUE (dom) - || ! really_constant_p (TYPE_MAX_VALUE (dom))) - || (tree_int_cst_lt (op1, TYPE_MIN_VALUE (dom)) - || tree_int_cst_lt (TYPE_MAX_VALUE (dom), op1))) + /* Test for index in range. Break if not. */ + if (!dom + || (! TYPE_MIN_VALUE (dom) + || ! really_constant_p (TYPE_MIN_VALUE (dom))) + || (! TYPE_MAX_VALUE (dom) + || ! really_constant_p (TYPE_MAX_VALUE (dom))) + || (tree_int_cst_lt (op1, TYPE_MIN_VALUE (dom)) + || tree_int_cst_lt (TYPE_MAX_VALUE (dom), op1))) break; /* If we're looking at a non-external VAR_DECL, then the @@ -726,14 +737,14 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp, things the hard way with PLUS. */ if (DECL_BIT_FIELD_TYPE (field)) { - if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST) - size = DECL_SIZE_UNIT (field); + if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST) + size = DECL_SIZE_UNIT (field); addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0); addr = fold_convert (ptr_type_node, addr); addr = fold (build (PLUS_EXPR, ptr_type_node, addr, fold_convert (ptr_type_node, - byte_position (field)))); + byte_position (field)))); } else { @@ -787,35 +798,35 @@ mf_xform_derefs (void) { next = bb->next_bb; for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i)) - { - tree s = bsi_stmt (i); - - /* Only a few GIMPLE statements can reference memory. */ - switch (TREE_CODE (s)) - { - case MODIFY_EXPR: - mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s), - integer_one_node); - mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 1), EXPR_LOCUS (s), - integer_zero_node); - break; - - case RETURN_EXPR: - if (TREE_OPERAND (s, 0) != NULL_TREE) - { - if (TREE_CODE (TREE_OPERAND (s, 0)) == MODIFY_EXPR) - mf_xform_derefs_1 (&i, &TREE_OPERAND (TREE_OPERAND (s, 0), 1), - EXPR_LOCUS (s), integer_zero_node); - else - mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s), - integer_zero_node); - } - break; - - default: - ; - } - } + { + tree s = bsi_stmt (i); + + /* Only a few GIMPLE statements can reference memory. */ + switch (TREE_CODE (s)) + { + case MODIFY_EXPR: + mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s), + integer_one_node); + mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 1), EXPR_LOCUS (s), + integer_zero_node); + break; + + case RETURN_EXPR: + if (TREE_OPERAND (s, 0) != NULL_TREE) + { + if (TREE_CODE (TREE_OPERAND (s, 0)) == MODIFY_EXPR) + mf_xform_derefs_1 (&i, &TREE_OPERAND (TREE_OPERAND (s, 0), 1), + EXPR_LOCUS (s), integer_zero_node); + else + mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s), + integer_zero_node); + } + break; + + default: + ; + } + } bb = next; } while (bb && bb->index <= saved_last_basic_block); @@ -866,15 +877,15 @@ mx_register_decls (tree decl, tree *stmt_list) { /* Eligible decl? */ if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) - /* It must be a non-external, automatic variable. */ - && ! DECL_EXTERNAL (decl) - && ! TREE_STATIC (decl) - /* The decl must have its address taken. */ - && TREE_ADDRESSABLE (decl) - /* The type of the variable must be complete. */ - && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl)) - /* Don't process the same decl twice. */ - && ! mf_marked_p (decl)) + /* It must be a non-external, automatic variable. */ + && ! DECL_EXTERNAL (decl) + && ! TREE_STATIC (decl) + /* The decl must have its address taken. */ + && TREE_ADDRESSABLE (decl) + /* The type of the variable must be complete. */ + && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl)) + /* Don't process the same decl twice. */ + && ! mf_marked_p (decl)) { tree size = NULL_TREE, variable_name; tree unregister_fncall, unregister_fncall_params; @@ -904,9 +915,9 @@ mx_register_decls (tree decl, tree *stmt_list) else if (TREE_CODE (t) == TRY_FINALLY_EXPR) { /* We hope that this is the try/finally block sometimes - constructed by gimplify_bind_expr() for a BIND_EXPR - that contains VLAs. This very naive recursion - appears to be sufficient. */ + constructed by gimplify_bind_expr() for a BIND_EXPR + that contains VLAs. This very naive recursion + appears to be sufficient. */ initially_stmts = tsi_start (TREE_OPERAND (t, 0)); } @@ -914,7 +925,7 @@ mx_register_decls (tree decl, tree *stmt_list) { if (TREE_CODE (TREE_OPERAND(call, 0)) == ADDR_EXPR && TREE_OPERAND (TREE_OPERAND (call, 0), 0) == - implicit_built_in_decls [BUILT_IN_STACK_ALLOC]) + implicit_built_in_decls [BUILT_IN_STACK_ALLOC]) { tree stack_alloc_args = TREE_OPERAND (call, 1); tree stack_alloc_op1 = TREE_VALUE (stack_alloc_args); @@ -1130,6 +1141,13 @@ mudflap_register_call (tree obj, tree object_size, tree varname) call_stmt = build_function_call_expr (mf_register_fndecl, args); + /* Add an initial __mf_init() call to the list of registration calls. */ + if (enqueued_call_stmt_chain == NULL_TREE) + { + tree call2_stmt = build_function_call_expr (mf_init_fndecl, NULL_TREE); + append_to_statement_list (call2_stmt, &enqueued_call_stmt_chain); + } + append_to_statement_list (call_stmt, &enqueued_call_stmt_chain); } @@ -1246,7 +1264,8 @@ mudflap_finish_file (void) if (enqueued_call_stmt_chain) { - cgraph_build_static_cdtor ('I', enqueued_call_stmt_chain); + cgraph_build_static_cdtor ('I', enqueued_call_stmt_chain, + MAX_RESERVED_INIT_PRIORITY-1); enqueued_call_stmt_chain = 0; } } -- 2.30.2