aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@gcc.gnu.org>2016-02-04 22:54:52 +0000
committerPatrick Palka <ppalka@gcc.gnu.org>2016-02-04 22:54:52 +0000
commit618d6c1c4df3b6363de8564373578a73f605f27e (patch)
treec04eca8d743478926aef38372afd11444d227844 /gcc
parentd094128b5b35d96e1ceb2e3c86a4295414631f8f (diff)
downloadgcc-618d6c1c4df3b6363de8564373578a73f605f27e.zip
gcc-618d6c1c4df3b6363de8564373578a73f605f27e.tar.gz
gcc-618d6c1c4df3b6363de8564373578a73f605f27e.tar.bz2
Fix constexpr evaluation of comparisons involving pointer-to-members
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/constexpr.c22
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem5.C17
4 files changed, 47 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8637c4f..2b6362d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index b076991..05f6843 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 924b0fb..d7c75ed 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..b1318c4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem5.C
@@ -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));
+}