aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-eh.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-07-05 20:43:04 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-07-05 20:43:04 +0200
commitf2c3a8ce9c1f7073eefb55b3967bc87a7ade468e (patch)
tree2eeacbf76ccc11458581ff92eec25941410a3acf /gcc/tree-eh.c
parent49bf9170ebead1c2575291cd08716ce970e5f35a (diff)
downloadgcc-f2c3a8ce9c1f7073eefb55b3967bc87a7ade468e.zip
gcc-f2c3a8ce9c1f7073eefb55b3967bc87a7ade468e.tar.gz
gcc-f2c3a8ce9c1f7073eefb55b3967bc87a7ade468e.tar.bz2
re PR tree-optimization/49618 (When building uClibc with GCC 4.6.1 old_atexit is miscompiled)
PR tree-optimization/49618 * tree-eh.c (tree_could_trap_p) <case CALL_EXPR>: For DECL_WEAK t recurse on the decl. <case FUNCTION_DECL, case VAR_DECL>: For DECL_WEAK decls return true if expr isn't known to be defined in current TU or some other LTO partition. From-SVN: r175884
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r--gcc/tree-eh.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 5831d34..f10d72d 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2449,8 +2449,42 @@ tree_could_trap_p (tree expr)
case CALL_EXPR:
t = get_callee_fndecl (expr);
/* Assume that calls to weak functions may trap. */
- if (!t || !DECL_P (t) || DECL_WEAK (t))
+ if (!t || !DECL_P (t))
return true;
+ if (DECL_WEAK (t))
+ return tree_could_trap_p (t);
+ return false;
+
+ case FUNCTION_DECL:
+ /* Assume that accesses to weak functions may trap, unless we know
+ they are certainly defined in current TU or in some other
+ LTO partition. */
+ if (DECL_WEAK (expr))
+ {
+ struct cgraph_node *node;
+ if (!DECL_EXTERNAL (expr))
+ return false;
+ node = cgraph_function_node (cgraph_get_node (expr), NULL);
+ if (node && node->in_other_partition)
+ return false;
+ return true;
+ }
+ return false;
+
+ case VAR_DECL:
+ /* Assume that accesses to weak vars may trap, unless we know
+ they are certainly defined in current TU or in some other
+ LTO partition. */
+ if (DECL_WEAK (expr))
+ {
+ struct varpool_node *node;
+ if (!DECL_EXTERNAL (expr))
+ return false;
+ node = varpool_variable_node (varpool_get_node (expr), NULL);
+ if (node && node->in_other_partition)
+ return false;
+ return true;
+ }
return false;
default: