aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-06-11 17:01:23 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-06-11 17:01:23 -0400
commit9b0607def49d8e30128253635ec44771f7c03530 (patch)
treea98da6dca0c6e3ad3e616778fb314a3e406ed415 /gcc/cp
parent960a58b949d97b106bc3579e7c451d0f4f5749ac (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/cp/constexpr.c18
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)