summaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-12-07 07:35:11 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-12-07 07:35:11 +0000
commitc11b875d3fdbf7e8a9f033ef63f66f4ae305f214 (patch)
tree94cb96a4a951949b96e031fdf5a464a3bdc185de /gcc/fold-const.c
parent7e20c7a8ec6dad78e5306dacff4a6c65c934055e (diff)
downloadgcc-c11b875d3fdbf7e8a9f033ef63f66f4ae305f214.tar.gz
* symtab.c (symtab_node::equal_address_to): New function.
* cgraph.h (symtab_node::equal_address_to): Declare. * fold-const.c (fold_comparison, fold_binary_loc): Use it. * c-family/c-common.c: Refuse weaks for symbols that can not change visibility. * gcc.dg/addr_equal-1.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@218462 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c61
1 files changed, 24 insertions, 37 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index c268007415c..94d1cbfc2b2 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8985,7 +8985,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
}
}
/* For non-equal bases we can simplify if they are addresses
- of local binding decls or constants. */
+ declarations with different addresses. */
else if (indirect_base0 && indirect_base1
/* We know that !operand_equal_p (base0, base1, 0)
because the if condition was false. But make
@@ -8993,16 +8993,13 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
&& base0 != base1
&& TREE_CODE (arg0) == ADDR_EXPR
&& TREE_CODE (arg1) == ADDR_EXPR
- && (((TREE_CODE (base0) == VAR_DECL
- || TREE_CODE (base0) == PARM_DECL)
- && (targetm.binds_local_p (base0)
- || CONSTANT_CLASS_P (base1)))
- || CONSTANT_CLASS_P (base0))
- && (((TREE_CODE (base1) == VAR_DECL
- || TREE_CODE (base1) == PARM_DECL)
- && (targetm.binds_local_p (base1)
- || CONSTANT_CLASS_P (base0)))
- || CONSTANT_CLASS_P (base1)))
+ && DECL_P (base0)
+ && DECL_P (base1)
+ /* Watch for aliases. */
+ && (!decl_in_symtab_p (base0)
+ || !decl_in_symtab_p (base1)
+ || !symtab_node::get_create (base0)->equal_address_to
+ (symtab_node::get_create (base1))))
{
if (code == EQ_EXPR)
return omit_two_operands_loc (loc, type, boolean_false_node,
@@ -12257,33 +12254,23 @@ fold_binary_loc (location_t loc,
unaliased symbols neither of which are extern (since we do not
have access to attributes for externs), then we know the result. */
if (TREE_CODE (arg0) == ADDR_EXPR
- && VAR_OR_FUNCTION_DECL_P (TREE_OPERAND (arg0, 0))
- && ! DECL_WEAK (TREE_OPERAND (arg0, 0))
- && ! lookup_attribute ("alias",
- DECL_ATTRIBUTES (TREE_OPERAND (arg0, 0)))
- && ! DECL_EXTERNAL (TREE_OPERAND (arg0, 0))
+ && DECL_P (TREE_OPERAND (arg0, 0))
&& TREE_CODE (arg1) == ADDR_EXPR
- && VAR_OR_FUNCTION_DECL_P (TREE_OPERAND (arg1, 0))
- && ! DECL_WEAK (TREE_OPERAND (arg1, 0))
- && ! lookup_attribute ("alias",
- DECL_ATTRIBUTES (TREE_OPERAND (arg1, 0)))
- && ! DECL_EXTERNAL (TREE_OPERAND (arg1, 0)))
- {
- /* We know that we're looking at the address of two
- non-weak, unaliased, static _DECL nodes.
-
- It is both wasteful and incorrect to call operand_equal_p
- to compare the two ADDR_EXPR nodes. It is wasteful in that
- all we need to do is test pointer equality for the arguments
- to the two ADDR_EXPR nodes. It is incorrect to use
- operand_equal_p as that function is NOT equivalent to a
- C equality test. It can in fact return false for two
- objects which would test as equal using the C equality
- operator. */
- bool equal = TREE_OPERAND (arg0, 0) == TREE_OPERAND (arg1, 0);
- return constant_boolean_node (equal
- ? code == EQ_EXPR : code != EQ_EXPR,
- type);
+ && DECL_P (TREE_OPERAND (arg1, 0)))
+ {
+ int equal;
+
+ if (decl_in_symtab_p (TREE_OPERAND (arg0, 0))
+ && decl_in_symtab_p (TREE_OPERAND (arg1, 0)))
+ equal = symtab_node::get_create (TREE_OPERAND (arg0, 0))
+ ->equal_address_to (symtab_node::get_create
+ (TREE_OPERAND (arg1, 0)));
+ else
+ equal = TREE_OPERAND (arg0, 0) == TREE_OPERAND (arg1, 0);
+ if (equal != 2)
+ return constant_boolean_node (equal
+ ? code == EQ_EXPR : code != EQ_EXPR,
+ type);
}
/* Similarly for a NEGATE_EXPR. */