aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-12-19 00:57:52 -0500
committerJason Merrill <jason@gcc.gnu.org>2011-12-19 00:57:52 -0500
commit37ef545a763f325576a837b39d5a908c5e5ca1d9 (patch)
tree63d5f57ed50f1cb0252282dcfd003c083ac7482b /gcc
parenta733dd3dedf9f193e23f11947d9b2a0bb1d68bcf (diff)
downloadgcc-37ef545a763f325576a837b39d5a908c5e5ca1d9.zip
gcc-37ef545a763f325576a837b39d5a908c5e5ca1d9.tar.gz
gcc-37ef545a763f325576a837b39d5a908c5e5ca1d9.tar.bz2
re PR c++/51489 (constexpr not working consistently)
PR c++/51489 * semantics.c (cxx_eval_outermost_constant_expr): Check for conversion from pointer to integer here. (cxx_eval_constant_expression) [NOP_EXPR]: Not here. From-SVN: r182470
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/semantics.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub.C14
4 files changed, 42 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7d625ee..6f1bc26 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2011-12-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/51489
+ * semantics.c (cxx_eval_outermost_constant_expr): Check for
+ conversion from pointer to integer here.
+ (cxx_eval_constant_expression) [NOP_EXPR]: Not here.
+
2011-12-18 Paolo Carlini <paolo.carlini@oracle.com>
* semantics.c (finish_compound_literal): Don't call check_narrowing
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 76b0b18..e73b40a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7704,17 +7704,6 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
tree oldop = TREE_OPERAND (t, 0);
tree op = oldop;
tree to = TREE_TYPE (t);
- tree source = TREE_TYPE (op);
- if (TYPE_PTR_P (source) && ARITHMETIC_TYPE_P (to)
- && !(TREE_CODE (op) == COMPONENT_REF
- && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (op, 0)))))
- {
- if (!allow_non_constant)
- error ("conversion of expression %qE of pointer type "
- "cannot yield a constant expression", op);
- *non_constant_p = true;
- return t;
- }
op = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
allow_non_constant, addr,
non_constant_p);
@@ -7803,6 +7792,20 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant)
non_constant_p = true;
}
+ /* Technically we should check this for all subexpressions, but that
+ runs into problems with our internal representation of pointer
+ subtraction and the 5.19 rules are still in flux. */
+ if (CONVERT_EXPR_CODE_P (TREE_CODE (r))
+ && ARITHMETIC_TYPE_P (TREE_TYPE (r))
+ && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
+ {
+ if (!allow_non_constant)
+ error ("conversion from pointer type %qT "
+ "to arithmetic type %qT in a constant-expression",
+ TREE_TYPE (TREE_OPERAND (r, 0)), TREE_TYPE (r));
+ non_constant_p = true;
+ }
+
if (non_constant_p && !allow_non_constant)
return error_mark_node;
else if (non_constant_p && TREE_CONSTANT (t))
@@ -8110,25 +8113,10 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
case NOP_EXPR:
case CONVERT_EXPR:
case VIEW_CONVERT_EXPR:
- /* -- an array-to-pointer conversion that is applied to an lvalue
- that designates an object with thread or automatic storage
- duration; FIXME not implemented as it breaks constexpr arrays;
- need to fix the standard
- -- a type conversion from a pointer or pointer-to-member type
- to a literal type. */
+ /* -- a reinterpret_cast. FIXME not implemented, and this rule
+ may change to something more specific to type-punning (DR 1312). */
{
tree from = TREE_OPERAND (t, 0);
- tree source = TREE_TYPE (from);
- tree target = TREE_TYPE (t);
- if (TYPE_PTR_P (source) && ARITHMETIC_TYPE_P (target)
- && !(TREE_CODE (from) == COMPONENT_REF
- && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (from, 0)))))
- {
- if (flags & tf_error)
- error ("conversion of expression %qE of pointer type "
- "cannot yield a constant expression", from);
- return false;
- }
return (potential_constant_expression_1
(from, TREE_CODE (t) != VIEW_CONVERT_EXPR, flags));
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9562a9d..dc77cbe 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-12-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/51489
+ * g++.dg/cpp0x/constexpr-ptrsub.C: New.
+
2011-12-18 Hans-Peter Nilsson <hp@axis.com>
* gcc.dg/pr51491-2.c: Fix "cleanup-treee-dump" typo.
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub.C
new file mode 100644
index 0000000..bccec73
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub.C
@@ -0,0 +1,14 @@
+// PR c++/51489
+// DR 1313
+// { dg-options "-std=c++0x" }
+
+struct array
+{
+ constexpr array() :x(0) {}
+ constexpr int const* begin() { return &x; }
+ int x;
+};
+constexpr array aa;
+constexpr auto b = aa.begin();
+static_assert(b-b == 0, "compiles just fine");
+static_assert(aa.begin()-aa.begin() == 0, "compiler thinks it's not a constant expression");