summaryrefslogtreecommitdiff
path: root/gcc/symtab.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-13 22:12:54 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-13 22:12:54 +0000
commit56ac70edf859395254334384649a463a9a801da2 (patch)
tree205f9c439effd6b0b1d8538404e92216504a3f4c /gcc/symtab.c
parentb57f4dfbceaa0a592b6d455b7037a6bfc30c5632 (diff)
downloadgcc-56ac70edf859395254334384649a463a9a801da2.tar.gz
* cgraph.h (symtab_node): Add nonzero_address.
(decl_in_symtab_p): Break out from ... (symtab_get_node): ... here. * fold-const.c: Include cgraph.h (tree_single_nonzero_warnv_p): Use symtab to determine if symbol is non-zero. * symtab.c (symtab_node::nonzero_address): New method. * gcc.dg/pr36901.h: Simplify because non-zero symbol folding no longer happens during parsing. * gcc.dg/pr44024.c: Update template. * g++.dg/tree-ssa/nonzero-2.C: New testcase. * g++.dg/tree-ssa/nonzero-1.C: New testcase. * gcc.dg/tree-ssa/nonzero-1.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212499 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/symtab.c')
-rw-r--r--gcc/symtab.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/gcc/symtab.c b/gcc/symtab.c
index deb317d1fb3..3a59935d132 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -1890,4 +1890,67 @@ symtab_get_symbol_partitioning_class (symtab_node *node)
return SYMBOL_PARTITION;
}
+
+/* Return true when symbol is known to be non-zero. */
+
+bool
+symtab_node::nonzero_address ()
+{
+ /* Weakrefs may be NULL when their target is not defined. */
+ if (this->alias && this->weakref)
+ {
+ if (this->analyzed)
+ {
+ symtab_node *target = symtab_alias_ultimate_target (this);
+
+ if (target->alias && target->weakref)
+ return false;
+ /* We can not recurse to target::nonzero. It is possible that the
+ target is used only via the alias.
+ We may walk references and look for strong use, but we do not know
+ if this strong use will survive to final binary, so be
+ conservative here.
+ ??? Maybe we could do the lookup during late optimization that
+ could be useful to eliminate the NULL pointer checks in LTO
+ programs. */
+ if (target->definition && !DECL_EXTERNAL (target->decl))
+ return true;
+ if (target->resolution != LDPR_UNKNOWN
+ && target->resolution != LDPR_UNDEF
+ && flag_delete_null_pointer_checks)
+ return true;
+ return false;
+ }
+ else
+ return false;
+ }
+
+ /* With !flag_delete_null_pointer_checks we assume that symbols may
+ bind to NULL. This is on by default on embedded targets only.
+
+ Otherwise all non-WEAK symbols must be defined and thus non-NULL or
+ linking fails. Important case of WEAK we want to do well are comdats.
+ Those are handled by later check for definition.
+
+ When parsing, beware the cases when WEAK attribute is added later. */
+ if (!DECL_WEAK (this->decl)
+ && flag_delete_null_pointer_checks
+ && cgraph_state > CGRAPH_STATE_PARSING)
+ return true;
+
+ /* If target is defined and not extern, we know it will be output and thus
+ it will bind to non-NULL.
+ Play safe for flag_delete_null_pointer_checks where weak definition maye
+ be re-defined by NULL. */
+ if (this->definition && !DECL_EXTERNAL (this->decl)
+ && (flag_delete_null_pointer_checks || !DECL_WEAK (this->decl)))
+ return true;
+
+ /* As the last resort, check the resolution info. */
+ if (this->resolution != LDPR_UNKNOWN
+ && this->resolution != LDPR_UNDEF
+ && flag_delete_null_pointer_checks)
+ return true;
+ return false;
+}
#include "gt-symtab.h"