diff options
author | Jason Merrill <jason@redhat.com> | 2018-06-11 17:01:23 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-06-11 17:01:23 -0400 |
commit | 9b0607def49d8e30128253635ec44771f7c03530 (patch) | |
tree | a98da6dca0c6e3ad3e616778fb314a3e406ed415 /gcc/cp | |
parent | 960a58b949d97b106bc3579e7c451d0f4f5749ac (diff) | |
download | gcc-9b0607def49d8e30128253635ec44771f7c03530.zip gcc-9b0607def49d8e30128253635ec44771f7c03530.tar.gz gcc-9b0607def49d8e30128253635ec44771f7c03530.tar.bz2 |
Fix ptrmem comparison for unions.
* constexpr.c (cxx_eval_binary_expression): Special case comparison
of pointers to members of the same union.
From-SVN: r261454
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 18 |
2 files changed, 21 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 595a08f..4c7041b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2018-06-05 Jason Merrill <jason@redhat.com> + + * constexpr.c (cxx_eval_binary_expression): Special case comparison + of pointers to members of the same union. + 2018-06-11 Jason Merrill <jason@redhat.com> PR c++/86094 - wrong code with defaulted move ctor. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 944c1cd..97a3385 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2051,8 +2051,22 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, if (TREE_CODE (lhs) == PTRMEM_CST && TREE_CODE (rhs) == PTRMEM_CST) - r = constant_boolean_node (cp_tree_equal (lhs, rhs) == is_code_eq, - type); + { + tree lmem = PTRMEM_CST_MEMBER (lhs); + tree rmem = PTRMEM_CST_MEMBER (rhs); + bool eq; + if (TREE_CODE (lmem) == TREE_CODE (rmem) + && TREE_CODE (lmem) == FIELD_DECL + && TREE_CODE (DECL_CONTEXT (lmem)) == UNION_TYPE + && same_type_p (DECL_CONTEXT (lmem), + DECL_CONTEXT (rmem))) + /* If both refer to (possibly different) members of the same union + (12.3), they compare equal. */ + eq = true; + else + eq = cp_tree_equal (lhs, rhs); + r = constant_boolean_node (eq == is_code_eq, type); + } else if ((TREE_CODE (lhs) == PTRMEM_CST || TREE_CODE (rhs) == PTRMEM_CST) && (null_member_pointer_value_p (lhs) |