From: ppalka Date: Thu, 4 Feb 2016 22:54:52 +0000 (+0000) Subject: Fix constexpr evaluation of comparisons involving pointer-to-members X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f7ef53928bc90411d40404ce42dc2c3dfc33c2fb;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233158 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8637c4fffa0f..2b6362daf2f6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2016-02-04 Patrick Palka + + * constexpr.c (cxx_eval_binary_expression): Fold equality + comparisons involving PTRMEM_CSTs. + 2016-02-04 Jakub Jelinek * class.c (find_flexarrays): Don't declare dom variable. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index b0769914d452..05f68435cd05 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 924b0fbefb56..d7c75ed705b0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-02-04 Patrick Palka + + * g++.dg/cpp0x/constexpr-ptrmem5.C: New test. + 2016-02-04 Jakub Jelinek PR c/69669 @@ -81,7 +85,7 @@ 2016-02-03 Patrick Palka PR c++/69056 - g++.dg/cpp0x/pr69056.C: New test. + * g++.dg/cpp0x/pr69056.C: New test. 2016-02-03 Vladimir Makarov Alexandre Oliva 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 000000000000..b1318c4cd126 --- /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)); +}