aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.cc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2022-11-04 11:23:12 +0100
committerEric Botcazou <ebotcazou@adacore.com>2022-11-04 15:14:50 +0100
commit0bdf10bdf1b2c9f31e7e764dec4d56ea6044f943 (patch)
tree25b2ac3b00d05621a82a46657a3dd214fe1d3a72 /gcc/fold-const.cc
parent3e2bdf2460a34a2389dee813a2ba8ecf976f2ec9 (diff)
downloadgcc-0bdf10bdf1b2c9f31e7e764dec4d56ea6044f943.zip
gcc-0bdf10bdf1b2c9f31e7e764dec4d56ea6044f943.tar.gz
gcc-0bdf10bdf1b2c9f31e7e764dec4d56ea6044f943.tar.bz2
Fix recent thinko in operand_equal_p
There is a thinko in a recent improvement made to operand_equal_p where the code just looks at operand 2 of COMPONENT_REF, if it is present, to compare addresses. That's wrong because operand 2 contains the number of DECL_OFFSET_ALIGN-bit-sized words so, when DECL_OFFSET_ALIGN > 8, not all the bytes are included and some of them are in DECL_FIELD_BIT_OFFSET, see get_inner_reference for the model computation. In other words, you would need to compare operand 2 and DECL_OFFSET_ALIGN and DECL_FIELD_BIT_OFFSET in this situation, but I'm not sure this is worth the hassle in practice so the fix just removes this alternate handling. gcc/ * fold-const.cc (operand_compare::operand_equal_p) <COMPONENT_REF>: Do not take into account operand 2. (operand_compare::hash_operand) <COMPONENT_REF>: Likewise. gcc/testsuite/ * gnat.dg/opt99.adb: New test. * gnat.dg/opt99_pkg1.ads, gnat.dg/opt99_pkg1.adb: New helper. * gnat.dg/opt99_pkg2.ads: Likewise.
Diffstat (limited to 'gcc/fold-const.cc')
-rw-r--r--gcc/fold-const.cc18
1 files changed, 4 insertions, 14 deletions
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 7e1ea58..b89cac9 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -3377,9 +3377,6 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1,
if (compare_address
&& (flags & OEP_ADDRESS_OF_SAME_FIELD) == 0)
{
- if (TREE_OPERAND (arg0, 2)
- || TREE_OPERAND (arg1, 2))
- return OP_SAME_WITH_NULL (2);
tree field0 = TREE_OPERAND (arg0, 1);
tree field1 = TREE_OPERAND (arg1, 1);
@@ -3890,17 +3887,10 @@ operand_compare::hash_operand (const_tree t, inchash::hash &hstate,
if (sflags & OEP_ADDRESS_OF)
{
hash_operand (TREE_OPERAND (t, 0), hstate, flags);
- if (TREE_OPERAND (t, 2))
- hash_operand (TREE_OPERAND (t, 2), hstate,
- flags & ~OEP_ADDRESS_OF);
- else
- {
- tree field = TREE_OPERAND (t, 1);
- hash_operand (DECL_FIELD_OFFSET (field),
- hstate, flags & ~OEP_ADDRESS_OF);
- hash_operand (DECL_FIELD_BIT_OFFSET (field),
- hstate, flags & ~OEP_ADDRESS_OF);
- }
+ hash_operand (DECL_FIELD_OFFSET (TREE_OPERAND (t, 1)),
+ hstate, flags & ~OEP_ADDRESS_OF);
+ hash_operand (DECL_FIELD_BIT_OFFSET (TREE_OPERAND (t, 1)),
+ hstate, flags & ~OEP_ADDRESS_OF);
return;
}
break;