diff options
author | Jan Hubicka <jh@suse.cz> | 2020-11-19 20:16:26 +0100 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2020-11-19 20:16:26 +0100 |
commit | 0862d007b564eca8c9a48fca0e689dd3f90db828 (patch) | |
tree | 7637185cc5d739eb5085b3ab891bb250c7b68e1a /gcc/fold-const.c | |
parent | 8156cfaa4c45f1249bbdda29d04b4fef84b7eafe (diff) | |
download | gcc-0862d007b564eca8c9a48fca0e689dd3f90db828.zip gcc-0862d007b564eca8c9a48fca0e689dd3f90db828.tar.gz gcc-0862d007b564eca8c9a48fca0e689dd3f90db828.tar.bz2 |
Fix two bugs in operand_equal_p
* fold-const.c (operand_compare::operand_equal_p): Fix thinko in
COMPONENT_REF handling and guard types_same_for_odr by
virtual_method_call_p.
(operand_compare::hash_operand): Likewise.
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 820b08d..c2cf1a9 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3314,30 +3314,34 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, may be NULL when we're called to compare MEM_EXPRs. */ if (!OP_SAME_WITH_NULL (0)) return false; - /* Most of time we only need to compare FIELD_DECLs for equality. - However when determining address look into actual offsets. - These may match for unions and unshared record types. */ - flags &= ~OEP_ADDRESS_OF; - if (!OP_SAME (1)) - { - if (flags & OEP_ADDRESS_OF) - { - 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); - - if (!operand_equal_p (DECL_FIELD_OFFSET (field0), - DECL_FIELD_OFFSET (field1), flags) - || !operand_equal_p (DECL_FIELD_BIT_OFFSET (field0), - DECL_FIELD_BIT_OFFSET (field1), - flags)) - return false; - } - else - return false; - } + { + bool compare_address = flags & OEP_ADDRESS_OF; + + /* Most of time we only need to compare FIELD_DECLs for equality. + However when determining address look into actual offsets. + These may match for unions and unshared record types. */ + flags &= ~OEP_ADDRESS_OF; + if (!OP_SAME (1)) + { + if (compare_address) + { + 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); + + if (!operand_equal_p (DECL_FIELD_OFFSET (field0), + DECL_FIELD_OFFSET (field1), flags) + || !operand_equal_p (DECL_FIELD_BIT_OFFSET (field0), + DECL_FIELD_BIT_OFFSET (field1), + flags)) + return false; + } + else + return false; + } + } return OP_SAME_WITH_NULL (2); case BIT_FIELD_REF: @@ -3436,10 +3440,14 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, if (!operand_equal_p (OBJ_TYPE_REF_OBJECT (arg0), OBJ_TYPE_REF_OBJECT (arg1), flags)) return false; - if (!types_same_for_odr (obj_type_ref_class (arg0), - obj_type_ref_class (arg1))) - return false; - return true; + if (virtual_method_call_p (arg0)) + { + if (!virtual_method_call_p (arg1)) + return false; + return types_same_for_odr (obj_type_ref_class (arg0), + obj_type_ref_class (arg1)); + } + return false; default: return false; @@ -3866,6 +3874,8 @@ operand_compare::hash_operand (const_tree t, inchash::hash &hstate, flags &= ~OEP_ADDRESS_OF; inchash::add_expr (OBJ_TYPE_REF_TOKEN (t), hstate, flags); inchash::add_expr (OBJ_TYPE_REF_OBJECT (t), hstate, flags); + if (!virtual_method_call_p (t)) + return; if (tree c = obj_type_ref_class (t)) { c = TYPE_NAME (TYPE_MAIN_VARIANT (c)); |