Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:agentdero:ada
gcc45
pr47278.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pr47278.diff of Package gcc45
2011-03-02 Richard Guenther <rguenther@suse.de> PR tree-optimization/47278 * tree.h (DECL_REPLACEABLE_P): Remove. (decl_replaceable_p): Declare. (decl_binds_to_current_def_p): Likewise. * varasm.c (decl_replaceable_p): New function. (decl_binds_to_current_def_p): Likewise. * cgraph.c (cgraph_function_body_availability): Use decl_replaceable_p. * tree-inline.c (inlinable_function_p): Likewise. cp/ * decl.c (finish_function): Use decl_replaceable_p. testsuite/ * gcc.dg/torture/pr47278-1.c: New testcase. * gcc.dg/torture/pr47278-2.c: Likewise. Index: gcc/testsuite/gcc.dg/torture/pr47278-1.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr47278-1.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr47278-1.c (revision 0) *************** *** 0 **** --- 1,4 ---- + /* { dg-do run } */ + /* { dg-additional-sources "pr47278-2.c" } */ + + int foo (void) { return 1; } Index: gcc/testsuite/gcc.dg/torture/pr47278-2.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr47278-2.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr47278-2.c (revision 0) *************** *** 0 **** --- 1,13 ---- + extern void abort (void); + + int __attribute__((weak,visibility("hidden"))) foo (void) + { + return 0; + } + + int main() + { + if (foo() != 1) + abort (); + return 0; + } Index: gcc/cgraph.c =================================================================== *** gcc/cgraph.c (revision 170616) --- gcc/cgraph.c (working copy) *************** cgraph_function_body_availability (struc *** 2093,2099 **** AVAIL_AVAILABLE here? That would be good reason to preserve this bit. */ ! else if (DECL_REPLACEABLE_P (node->decl) && !DECL_EXTERNAL (node->decl)) avail = AVAIL_OVERWRITABLE; else avail = AVAIL_AVAILABLE; --- 2093,2099 ---- AVAIL_AVAILABLE here? That would be good reason to preserve this bit. */ ! else if (decl_replaceable_p (node->decl) && !DECL_EXTERNAL (node->decl)) avail = AVAIL_OVERWRITABLE; else avail = AVAIL_AVAILABLE; Index: gcc/tree.h =================================================================== *** gcc/tree.h (revision 170616) --- gcc/tree.h (working copy) *************** struct GTY(()) tree_parm_decl { *** 2913,2938 **** #define DECL_COMDAT_GROUP(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_group) - /* A replaceable function is one which may be replaced at link-time - with an entirely different definition, provided that the - replacement has the same type. For example, functions declared - with __attribute__((weak)) on most systems are replaceable. - - COMDAT functions are not replaceable, since all definitions of the - function must be equivalent. It is important that COMDAT functions - not be treated as replaceable so that use of C++ template - instantiations is not penalized. - - For example, DECL_REPLACEABLE is used to determine whether or not a - function (including a template instantiation) which is not - explicitly declared "inline" can be inlined. If the function is - DECL_REPLACEABLE then it is not safe to do the inlining, since the - implementation chosen at link-time may be different. However, a - function that is not DECL_REPLACEABLE can be inlined, since all - versions of the function will be functionally identical. */ - #define DECL_REPLACEABLE_P(NODE) \ - (!DECL_COMDAT (NODE) && !targetm.binds_local_p (NODE)) - /* The name of the object as the assembler will see it (but before any translations made by ASM_OUTPUT_LABELREF). Often this is the same as DECL_NAME. It is an IDENTIFIER_NODE. */ --- 2913,2918 ---- *************** extern void finish_aliases_1 (void); *** 5145,5150 **** --- 5125,5132 ---- extern void finish_aliases_2 (void); extern tree emutls_decl (tree); extern void remove_unreachable_alias_pairs (void); + extern bool decl_replaceable_p (tree); + extern bool decl_binds_to_current_def_p (tree); /* In stmt.c */ extern void expand_computed_goto (tree); Index: gcc/cp/decl.c =================================================================== *** gcc/cp/decl.c (revision 170616) --- gcc/cp/decl.c (working copy) *************** finish_function (int flags) *** 12502,12508 **** if (!processing_template_decl && !cp_function_chain->can_throw && !flag_non_call_exceptions ! && !DECL_REPLACEABLE_P (fndecl)) TREE_NOTHROW (fndecl) = 1; /* This must come after expand_function_end because cleanups might --- 12502,12508 ---- if (!processing_template_decl && !cp_function_chain->can_throw && !flag_non_call_exceptions ! && !decl_replaceable_p (fndecl)) TREE_NOTHROW (fndecl) = 1; /* This must come after expand_function_end because cleanups might Index: gcc/varasm.c =================================================================== *** gcc/varasm.c (revision 170616) --- gcc/varasm.c (working copy) *************** default_binds_local_p_1 (const_tree exp, *** 6691,6696 **** --- 6691,6741 ---- return local_p; } + /* Return true when references to DECL must bind to current definition in + final executable. + + The condition is usually equivalent to whether the function binds to the + current module (shared library or executable), that is to binds_local_p. + We use this fact to avoid need for another target hook and implement + the logic using binds_local_p and just special cases where + decl_binds_to_current_def_p is stronger than binds local_p. In particular + the weak definitions (that can be overwritten at linktime by other + definition from different object file) and when resolution info is available + we simply use the knowledge passed to us by linker plugin. */ + bool + decl_binds_to_current_def_p (tree decl) + { + gcc_assert (DECL_P (decl)); + if (!TREE_PUBLIC (decl)) + return true; + if (!targetm.binds_local_p (decl)) + return false; + /* Otherwise we have to assume the worst for DECL_WEAK (hidden weaks + binds localy but still can be overwritten). + This rely on fact that binds_local_p behave as decl_replaceable_p + for all other declaration types. */ + return !DECL_WEAK (decl); + } + + /* A replaceable function or variable is one which may be replaced + at link-time with an entirely different definition, provided that the + replacement has the same type. For example, functions declared + with __attribute__((weak)) on most systems are replaceable. + + COMDAT functions are not replaceable, since all definitions of the + function must be equivalent. It is important that COMDAT functions + not be treated as replaceable so that use of C++ template + instantiations is not penalized. */ + + bool + decl_replaceable_p (tree decl) + { + gcc_assert (DECL_P (decl)); + if (!TREE_PUBLIC (decl) || DECL_COMDAT (decl)) + return false; + return !decl_binds_to_current_def_p (decl); + } + /* Default function to output code that will globalize a label. A target must define GLOBAL_ASM_OP or provide its own function to globalize a label. */ Index: gcc/tree-inline.c =================================================================== *** gcc/tree-inline.c (revision 170616) --- gcc/tree-inline.c (working copy) *************** tree_inlinable_function_p (tree fn) *** 3067,3073 **** /* Don't auto-inline anything that might not be bound within this unit of translation. */ else if (!DECL_DECLARED_INLINE_P (fn) ! && DECL_REPLACEABLE_P (fn)) inlinable = false; else if (!function_attribute_inlinable_p (fn)) --- 3067,3073 ---- /* Don't auto-inline anything that might not be bound within this unit of translation. */ else if (!DECL_DECLARED_INLINE_P (fn) ! && decl_replaceable_p (fn)) inlinable = false; else if (!function_attribute_inlinable_p (fn))
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor