+2011-03-08 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.
+
2011-03-07 Pat Haugen <pthaugen@us.ibm.com>
Backport from mainline
AVAIL_AVAILABLE here? That would be good reason to preserve this
bit. */
- else if (DECL_REPLACEABLE_P (node->decl) && !DECL_EXTERNAL (node->decl))
+ else if (decl_replaceable_p (node->decl) && !DECL_EXTERNAL (node->decl))
avail = AVAIL_OVERWRITABLE;
else avail = AVAIL_AVAILABLE;
+2011-03-08 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/47278
+ * decl.c (finish_function): Use decl_replaceable_p.
+
2011-03-01 Jason Merrill <jason@redhat.com>
PR c++/46159
if (!processing_template_decl
&& !cp_function_chain->can_throw
&& !flag_non_call_exceptions
- && !DECL_REPLACEABLE_P (fndecl))
+ && !decl_replaceable_p (fndecl))
TREE_NOTHROW (fndecl) = 1;
/* This must come after expand_function_end because cleanups might
+2011-03-08 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/47278
+ * gcc.dg/torture/pr47278-1.c: New testcase.
+ * gcc.dg/torture/pr47278-2.c: Likewise.
+
2011-03-07 Pat Haugen <pthaugen@us.ibm.com>
Backport from mainline
--- /dev/null
+/* { dg-do run } */
+/* { dg-additional-sources "pr47278-2.c" } */
+
+int foo (void) { return 1; }
--- /dev/null
+extern void abort (void);
+
+int __attribute__((weak,visibility("hidden"))) foo (void)
+{
+ return 0;
+}
+
+int main()
+{
+ if (foo() != 1)
+ abort ();
+ return 0;
+}
/* 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))
+ && decl_replaceable_p (fn))
inlinable = false;
else if (!function_attribute_inlinable_p (fn))
#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. */
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);
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. */