* tree.h (DECL_REPLACEABLE_P): New macro.
* except.c (set_nothrow_function_flags): Likewise.
PR target/29487
* decl.c (finish_function): Use DECL_REPLACEABLE.
* tree.c (cp_cannot_inline_tree_fn): Likewise.
PR c++/29487
* g++.dg/eh/weak1-C: New test.
* g++.dg/eh/weak1-a.cc: Likewise.
* g++.dg/eh/comdat1.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121819
138bc75d-0d04-0410-961f-
82ee72b054a4
+2007-02-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR target/29487
+ * tree.h (DECL_REPLACEABLE_P): New macro.
+ * except.c (set_nothrow_function_flags): Likewise.
+
2007-02-11 Tehila Meyzels <tehila@il.ibm.com>
Ira Rosen <irar@il.ibm.com>
Dorit Nuzman <dorit@il.ibm.com>
+2007-02-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR target/29487
+ * decl.c (finish_function): Use DECL_REPLACEABLE.
+ * tree.c (cp_cannot_inline_tree_fn): Likewise.
+
2007-02-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
* parser.c (cp_parser_primary_expression): Reformat overly long lines.
if (!processing_template_decl
&& !cp_function_chain->can_throw
&& !flag_non_call_exceptions
- && targetm.binds_local_p (fndecl))
+ && !DECL_REPLACEABLE_P (fndecl))
TREE_NOTHROW (fndecl) = 1;
/* This must come after expand_function_end because cleanups might
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
return 1;
- /* Don't auto-inline anything that might not be bound within
- this unit of translation.
- Exclude comdat functions from this rule. While they can be bound
- to the other unit, they all must be the same. This is especially
- important so templates can inline. */
- if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn)
- && !DECL_COMDAT (fn))
+ /* Don't auto-inline functions that might be replaced at link-time
+ with an alternative definition. */
+ if (!DECL_DECLARED_INLINE_P (fn) && DECL_REPLACEABLE_P (fn))
{
DECL_UNINLINABLE (fn) = 1;
return 1;
{
rtx insn;
- if (!targetm.binds_local_p (current_function_decl))
+ /* If we don't know that this implementation of the function will
+ actually be used, then we must not set TREE_NOTHROW, since
+ callers must not assume that this function does not throw. */
+ if (DECL_REPLACEABLE_P (current_function_decl))
return 0;
TREE_NOTHROW (current_function_decl) = 1;
+2007-02-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/29487
+ * g++.dg/eh/weak1-C: New test.
+ * g++.dg/eh/weak1-a.cc: Likewise.
+ * g++.dg/eh/comdat1.C: Likewise.
+
2007-02-11 Tehila Meyzels <tehila@il.ibm.com>
Dorit Nuzman <dorit@il.ibm.com>
--- /dev/null
+// PR target/29487
+// { dg-do link }
+// { dg-options "-O2" }
+
+/* This function is not defined. The compiler should optimize away
+ all calls to it. */
+extern void undefined () throw ();
+
+extern void f1();
+
+inline void f2() {
+ f1();
+}
+
+/* This function will be COMDAT if not inlined. */
+inline void f1() {}
+
+/* This function will be COMDAT. */
+template <typename T>
+void f3() {
+ if (false)
+ throw 3;
+}
+
+inline void f4() {
+ if (false)
+ throw 7;
+}
+
+int main () {
+ try {
+ f1();
+ f2();
+ f3<int>();
+ f4();
+ } catch (...) {
+ /* The compiler should recognize that none of the functions above
+ can throw exceptions, and therefore remove this code as
+ unreachable. */
+ undefined ();
+ }
+}
--- /dev/null
+extern void f() {
+ throw 7;
+}
--- /dev/null
+// PR target/29487
+// { dg-require-weak "" }
+// { dg-do run { xfail "hppa*-hp-hpux11.*" } }
+// { dg-additional-sources "weak1-a.cc" }
+// { dg-options "-O2" }
+
+extern __attribute__((weak))
+void f() {
+}
+
+int main () {
+ try {
+ f();
+ return 1;
+ } catch (int i) {
+ /* Although the implementation of f in this file does not throw
+ any exceptions, it is weak, and may therefore be replaced at
+ link time. Therefore, the compiler must not optimize away this
+ catch clause. */
+ if (i != 7)
+ return 2;
+ }
+}
something which is DECL_COMDAT. */
#define DECL_COMDAT(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_flag)
+/* 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. */