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> 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. * cp-tree.h (class iloc_sentinel): New.
* decl.c (grokdeclarator, finish_enum_value_list): Use it. * decl.c (grokdeclarator, finish_enum_value_list): Use it.
* mangle.c (mangle_decl_string): 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) if (TREE_CODE (op) == CONST_DECL)
return DECL_INITIAL (op); return DECL_INITIAL (op);
/* *&p => p; make sure to handle *&"str"[cst] here. */ /* *&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); tree fop = fold_read_from_constant_string (op);
if (fop) if (fop)
@ -3398,8 +3398,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
} }
/* *(foo *)&fooarray => fooarray[0] */ /* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE else if (TREE_CODE (optype) == ARRAY_TYPE
&& (same_type_ignoring_top_level_qualifiers_p && similar_type_p (type, TREE_TYPE (optype)))
(type, TREE_TYPE (optype))))
{ {
tree type_domain = TYPE_DOMAIN (optype); tree type_domain = TYPE_DOMAIN (optype);
tree min_val = size_zero_node; 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 */ /* *(foo *)&complexfoo => __real__ complexfoo */
else if (TREE_CODE (optype) == COMPLEX_TYPE else if (TREE_CODE (optype) == COMPLEX_TYPE
&& (same_type_ignoring_top_level_qualifiers_p && similar_type_p (type, TREE_TYPE (optype)))
(type, TREE_TYPE (optype))))
return fold_build1_loc (loc, REALPART_EXPR, type, op); return fold_build1_loc (loc, REALPART_EXPR, type, op);
/* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */ /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
else if (VECTOR_TYPE_P (optype) else if (VECTOR_TYPE_P (optype)
&& (same_type_ignoring_top_level_qualifiers_p && similar_type_p (type, TREE_TYPE (optype)))
(type, TREE_TYPE (optype))))
{ {
tree part_width = TYPE_SIZE (type); tree part_width = TYPE_SIZE (type);
tree index = bitsize_int (0); 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 if (TREE_CODE (field) == FIELD_DECL
&& TREE_TYPE (field) != error_mark_node && TREE_TYPE (field) != error_mark_node
&& integer_zerop (byte_position (field)) && integer_zerop (byte_position (field))
&& (same_type_ignoring_top_level_qualifiers_p && similar_type_p (TREE_TYPE (field), type))
(TREE_TYPE (field), type)))
return fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE); 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,...> */ /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
if (VECTOR_TYPE_P (op00type) if (VECTOR_TYPE_P (op00type)
&& same_type_ignoring_top_level_qualifiers_p && similar_type_p (type, TREE_TYPE (op00type))
(type, TREE_TYPE (op00type))
/* POINTER_PLUS_EXPR second operand is sizetype, unsigned, /* POINTER_PLUS_EXPR second operand is sizetype, unsigned,
but we want to treat offsets with MSB set as negative. but we want to treat offsets with MSB set as negative.
For the code below negative offsets are invalid and 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 */ /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
else if (TREE_CODE (op00type) == COMPLEX_TYPE else if (TREE_CODE (op00type) == COMPLEX_TYPE
&& (same_type_ignoring_top_level_qualifiers_p && similar_type_p (type, TREE_TYPE (op00type)))
(type, TREE_TYPE (op00type))))
{ {
if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)), if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)),
const_op01)) 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] */ /* ((foo *)&fooarray)[1] => fooarray[1] */
else if (TREE_CODE (op00type) == ARRAY_TYPE else if (TREE_CODE (op00type) == ARRAY_TYPE
&& (same_type_ignoring_top_level_qualifiers_p && similar_type_p (type, TREE_TYPE (op00type)))
(type, TREE_TYPE (op00type))))
{ {
tree type_domain = TYPE_DOMAIN (op00type); tree type_domain = TYPE_DOMAIN (op00type);
tree min_val = size_zero_node; 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 if (TREE_CODE (field) == FIELD_DECL
&& TREE_TYPE (field) != error_mark_node && TREE_TYPE (field) != error_mark_node
&& tree_int_cst_equal (byte_position (field), op01) && tree_int_cst_equal (byte_position (field), op01)
&& (same_type_ignoring_top_level_qualifiers_p && similar_type_p (TREE_TYPE (field), type))
(TREE_TYPE (field), type)))
return fold_build3 (COMPONENT_REF, type, op00, return fold_build3 (COMPONENT_REF, type, op00,
field, NULL_TREE); 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] */ /* *(foo *)fooarrptr => (*fooarrptr)[0] */
else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
&& (same_type_ignoring_top_level_qualifiers_p && similar_type_p (type, TREE_TYPE (TREE_TYPE (subtype))))
(type, TREE_TYPE (TREE_TYPE (subtype)))))
{ {
tree type_domain; tree type_domain;
tree min_val = size_zero_node; tree min_val = size_zero_node;
@ -3611,13 +3602,14 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
STRIP_NOPS (sub); STRIP_NOPS (sub);
if (TREE_CODE (sub) == ADDR_EXPR) 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))); (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
/* DR 1188 says we don't have to deal with this. */ /* DR 1188 says we don't have to deal with this. */
if (!ctx->quiet) if (!ctx->quiet)
error ("accessing value of %qE through a %qT glvalue in a " error_at (cp_expr_loc_or_input_loc (t),
"constant expression", build_fold_indirect_ref (sub), "accessing value of %qE through a %qT glvalue in a "
TREE_TYPE (t)); "constant expression", build_fold_indirect_ref (sub),
TREE_TYPE (t));
*non_constant_p = true; *non_constant_p = true;
return t; 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;