constexpr.c (cxx_fold_indirect_ref): Use similar_type_p.
* constexpr.c (cxx_fold_indirect_ref): Use similar_type_p. Merging the similar_type_p change to the concepts branch broke a cmcstl2 testcase; investigating led me to this small testcase which has always failed on trunk. (cxx_eval_indirect_ref): Likewise. Improve error location. From-SVN: r276192
This commit is contained in:
parent
c872f1506d
commit
1a120ec124
|
@ -1,5 +1,8 @@
|
|||
2019-09-27 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* constexpr.c (cxx_fold_indirect_ref): Use similar_type_p.
|
||||
(cxx_eval_indirect_ref): Likewise. Improve error location.
|
||||
|
||||
* cp-tree.h (class iloc_sentinel): New.
|
||||
* decl.c (grokdeclarator, finish_enum_value_list): Use it.
|
||||
* mangle.c (mangle_decl_string): Use it.
|
||||
|
|
|
@ -3388,7 +3388,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
|
|||
if (TREE_CODE (op) == CONST_DECL)
|
||||
return DECL_INITIAL (op);
|
||||
/* *&p => p; make sure to handle *&"str"[cst] here. */
|
||||
if (same_type_ignoring_tlq_and_bounds_p (optype, type))
|
||||
if (similar_type_p (optype, type))
|
||||
{
|
||||
tree fop = fold_read_from_constant_string (op);
|
||||
if (fop)
|
||||
|
@ -3398,8 +3398,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
|
|||
}
|
||||
/* *(foo *)&fooarray => fooarray[0] */
|
||||
else if (TREE_CODE (optype) == ARRAY_TYPE
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(type, TREE_TYPE (optype))))
|
||||
&& similar_type_p (type, TREE_TYPE (optype)))
|
||||
{
|
||||
tree type_domain = TYPE_DOMAIN (optype);
|
||||
tree min_val = size_zero_node;
|
||||
|
@ -3410,13 +3409,11 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
|
|||
}
|
||||
/* *(foo *)&complexfoo => __real__ complexfoo */
|
||||
else if (TREE_CODE (optype) == COMPLEX_TYPE
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(type, TREE_TYPE (optype))))
|
||||
&& similar_type_p (type, TREE_TYPE (optype)))
|
||||
return fold_build1_loc (loc, REALPART_EXPR, type, op);
|
||||
/* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
|
||||
else if (VECTOR_TYPE_P (optype)
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(type, TREE_TYPE (optype))))
|
||||
&& similar_type_p (type, TREE_TYPE (optype)))
|
||||
{
|
||||
tree part_width = TYPE_SIZE (type);
|
||||
tree index = bitsize_int (0);
|
||||
|
@ -3440,8 +3437,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
|
|||
if (TREE_CODE (field) == FIELD_DECL
|
||||
&& TREE_TYPE (field) != error_mark_node
|
||||
&& integer_zerop (byte_position (field))
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(TREE_TYPE (field), type)))
|
||||
&& similar_type_p (TREE_TYPE (field), type))
|
||||
return fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE);
|
||||
}
|
||||
}
|
||||
|
@ -3460,8 +3456,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
|
|||
|
||||
/* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
|
||||
if (VECTOR_TYPE_P (op00type)
|
||||
&& same_type_ignoring_top_level_qualifiers_p
|
||||
(type, TREE_TYPE (op00type))
|
||||
&& similar_type_p (type, TREE_TYPE (op00type))
|
||||
/* POINTER_PLUS_EXPR second operand is sizetype, unsigned,
|
||||
but we want to treat offsets with MSB set as negative.
|
||||
For the code below negative offsets are invalid and
|
||||
|
@ -3486,8 +3481,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
|
|||
}
|
||||
/* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
|
||||
else if (TREE_CODE (op00type) == COMPLEX_TYPE
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(type, TREE_TYPE (op00type))))
|
||||
&& similar_type_p (type, TREE_TYPE (op00type)))
|
||||
{
|
||||
if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)),
|
||||
const_op01))
|
||||
|
@ -3495,8 +3489,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
|
|||
}
|
||||
/* ((foo *)&fooarray)[1] => fooarray[1] */
|
||||
else if (TREE_CODE (op00type) == ARRAY_TYPE
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(type, TREE_TYPE (op00type))))
|
||||
&& similar_type_p (type, TREE_TYPE (op00type)))
|
||||
{
|
||||
tree type_domain = TYPE_DOMAIN (op00type);
|
||||
tree min_val = size_zero_node;
|
||||
|
@ -3531,8 +3524,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
|
|||
if (TREE_CODE (field) == FIELD_DECL
|
||||
&& TREE_TYPE (field) != error_mark_node
|
||||
&& tree_int_cst_equal (byte_position (field), op01)
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(TREE_TYPE (field), type)))
|
||||
&& similar_type_p (TREE_TYPE (field), type))
|
||||
return fold_build3 (COMPONENT_REF, type, op00,
|
||||
field, NULL_TREE);
|
||||
}
|
||||
|
@ -3540,8 +3532,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
|
|||
}
|
||||
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
|
||||
else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(type, TREE_TYPE (TREE_TYPE (subtype)))))
|
||||
&& similar_type_p (type, TREE_TYPE (TREE_TYPE (subtype))))
|
||||
{
|
||||
tree type_domain;
|
||||
tree min_val = size_zero_node;
|
||||
|
@ -3611,13 +3602,14 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
|
|||
STRIP_NOPS (sub);
|
||||
if (TREE_CODE (sub) == ADDR_EXPR)
|
||||
{
|
||||
gcc_assert (!same_type_ignoring_top_level_qualifiers_p
|
||||
gcc_assert (!similar_type_p
|
||||
(TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
|
||||
/* DR 1188 says we don't have to deal with this. */
|
||||
if (!ctx->quiet)
|
||||
error ("accessing value of %qE through a %qT glvalue in a "
|
||||
"constant expression", build_fold_indirect_ref (sub),
|
||||
TREE_TYPE (t));
|
||||
error_at (cp_expr_loc_or_input_loc (t),
|
||||
"accessing value of %qE through a %qT glvalue in a "
|
||||
"constant expression", build_fold_indirect_ref (sub),
|
||||
TREE_TYPE (t));
|
||||
*non_constant_p = true;
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
// { dg-do compile { target c++11 } }
|
||||
|
||||
int i = 42;
|
||||
constexpr int *p = &i;
|
||||
constexpr int const *const *q = &p;
|
||||
constexpr int const *r = *q;
|
Loading…
Reference in New Issue