mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-25 01:30:44 +08:00
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
This commit is contained in:
parent
a733dd3ded
commit
37ef545a76
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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.
|
||||
|
14
gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub.C
Normal file
14
gcc/testsuite/g++.dg/cpp0x/constexpr-ptrsub.C
Normal file
@ -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");
|
Loading…
x
Reference in New Issue
Block a user