Commit 1a120ec1 by Jason Merrill Committed by Jason Merrill

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
parent c872f150
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.
......
...@@ -3388,7 +3388,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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;
} }
......
// { dg-do compile { target c++11 } }
int i = 42;
constexpr int *p = &i;
constexpr int const *const *q = &p;
constexpr int const *r = *q;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment