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:
Jason Merrill 2019-09-27 14:23:10 -04:00 committed by Jason Merrill
parent c872f1506d
commit 1a120ec124
3 changed files with 24 additions and 23 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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;