+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.
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)
--- /dev/null
+/* [expr.eq] If both refer to (possibly different) members of the same union
+ (12.3), they compare equal. */
+// { dg-do run { target c++11 } }
+// { dg-additional-options -O }
+
+union U
+{
+ int i;
+ int j;
+};
+
+#define SA(X) static_assert ((X),#X)
+SA (&U::i == &U::j);
+SA (!(&U::i != &U::j));
+
+#define assert(X) do { if (!(X)) __builtin_abort(); } while(0)
+
+void f (int U::*p, int U::*q)
+{
+ assert (p==q);
+ assert (!(p!=q));
+}
+
+int main()
+{
+ assert (&U::i == &U::j);
+ assert (!(&U::i != &U::j));
+}