]> gcc.gnu.org Git - gcc.git/commitdiff
Fix constexpr evaluation of comparisons involving pointer-to-members
authorPatrick Palka <ppalka@gcc.gnu.org>
Thu, 4 Feb 2016 22:54:52 +0000 (22:54 +0000)
committerPatrick Palka <ppalka@gcc.gnu.org>
Thu, 4 Feb 2016 22:54:52 +0000 (22:54 +0000)
gcc/cp/ChangeLog:

* constexpr.c (cxx_eval_binary_expression): Fold equality
comparisons involving PTRMEM_CSTs.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/constexpr-ptrmem5.C: New test.

From-SVN: r233158

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem5.C [new file with mode: 0644]

index 8637c4fffa0faf9a6066829ae3bb035609863294..2b6362daf2f66b197c58e6b5fe86b41edb0cb51b 100644 (file)
@@ -1,3 +1,8 @@
+2016-02-04  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       * constexpr.c (cxx_eval_binary_expression): Fold equality
+       comparisons involving PTRMEM_CSTs.
+
 2016-02-04  Jakub Jelinek  <jakub@redhat.com>
 
        * class.c (find_flexarrays): Don't declare dom variable.
index b0769914d452feef4e586dce552c793b7a67cd29..05f68435cd051058428228ea2944b60af8a0f498 100644 (file)
@@ -1593,7 +1593,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
                            bool /*lval*/,
                            bool *non_constant_p, bool *overflow_p)
 {
-  tree r;
+  tree r = NULL_TREE;
   tree orig_lhs = TREE_OPERAND (t, 0);
   tree orig_rhs = TREE_OPERAND (t, 1);
   tree lhs, rhs;
@@ -1612,7 +1612,25 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
   location_t loc = EXPR_LOCATION (t);
   enum tree_code code = TREE_CODE (t);
   tree type = TREE_TYPE (t);
-  r = fold_binary_loc (loc, code, type, lhs, rhs);
+
+  if (code == EQ_EXPR || code == NE_EXPR)
+    {
+      bool is_code_eq = (code == EQ_EXPR);
+
+      if (TREE_CODE (lhs) == PTRMEM_CST
+         && TREE_CODE (rhs) == PTRMEM_CST)
+       r = constant_boolean_node (cp_tree_equal (lhs, rhs) == is_code_eq,
+                                  type);
+      else if ((TREE_CODE (lhs) == PTRMEM_CST
+               || TREE_CODE (rhs) == PTRMEM_CST)
+              && (null_member_pointer_value_p (lhs)
+                  || null_member_pointer_value_p (rhs)))
+       r = constant_boolean_node (!is_code_eq, type);
+    }
+
+  if (r == NULL_TREE)
+    r = fold_binary_loc (loc, code, type, lhs, rhs);
+
   if (r == NULL_TREE)
     {
       if (lhs == orig_lhs && rhs == orig_rhs)
index 924b0fbefb568537c3de772ada19e0aa822f612e..d7c75ed705b04c29719681dadb5fd608d2d48f22 100644 (file)
@@ -1,3 +1,7 @@
+2016-02-04  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       * g++.dg/cpp0x/constexpr-ptrmem5.C: New test.
+
 2016-02-04  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/69669
@@ -81,7 +85,7 @@
 2016-02-03  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c++/69056
-       g++.dg/cpp0x/pr69056.C: New test.
+       g++.dg/cpp0x/pr69056.C: New test.
 
 2016-02-03  Vladimir Makarov  <vmakarov@redhat.com>
            Alexandre Oliva  <aoliva@redhat.com>
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem5.C
new file mode 100644 (file)
index 0000000..b1318c4
--- /dev/null
@@ -0,0 +1,17 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(x) static_assert ((x), #x)
+
+struct X { int a, b; };
+
+void
+foo ()
+{
+  SA (&X::a);
+  SA (&X::a == &X::a);
+  SA (!(&X::a != &X::a));
+  SA (&X::a != &X::b);
+  SA (!(&X::a == &X::b));
+  SA ((!&X::b) == 0);
+  SA (!(&X::b == 0));
+}
This page took 0.086882 seconds and 5 git commands to generate.