diff options
author | Patrick Palka <ppalka@gcc.gnu.org> | 2016-02-04 22:54:52 +0000 |
---|---|---|
committer | Patrick Palka <ppalka@gcc.gnu.org> | 2016-02-04 22:54:52 +0000 |
commit | 618d6c1c4df3b6363de8564373578a73f605f27e (patch) | |
tree | c04eca8d743478926aef38372afd11444d227844 /gcc | |
parent | d094128b5b35d96e1ceb2e3c86a4295414631f8f (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem5.C | 17 |
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)); +} |