Commit e4511ca2 by Jason Merrill Committed by Jason Merrill

Avoid taking the address of something just because it's in parens.

	* constexpr.c (same_type_ignoring_tlq_and_bounds_p): New.
	(cxx_fold_indirect_ref): Use it.
	(cxx_eval_constant_expression) [VIEW_CONVERT_EXPR]: Use it.
	* cp-tree.h (REF_PARENTHESIZED_P): Allow VIEW_CONVERT_EXPR.
	* semantics.c (force_paren_expr): Use VIEW_CONVERT_EXPR instead of
	static_cast to reference type.
	(maybe_undo_parenthesized_ref): Handle VIEW_CONVERT_EXPR.

From-SVN: r261971
parent 73607ff9
2018-06-22 Jason Merrill <jason@redhat.com>
Avoid taking the address of something just because it's in parens.
* constexpr.c (same_type_ignoring_tlq_and_bounds_p): New.
(cxx_fold_indirect_ref): Use it.
(cxx_eval_constant_expression) [VIEW_CONVERT_EXPR]: Use it.
* cp-tree.h (REF_PARENTHESIZED_P): Allow VIEW_CONVERT_EXPR.
* semantics.c (force_paren_expr): Use VIEW_CONVERT_EXPR instead of
static_cast to reference type.
(maybe_undo_parenthesized_ref): Handle VIEW_CONVERT_EXPR.
2018-06-21 Jason Merrill <jason@redhat.com>
* pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Use TEMPLATE_PARM_DESCENDANTS.
......
......@@ -3076,6 +3076,23 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
return r;
}
/* Like same_type_ignoring_top_level_qualifiers_p, but also handle the case
where the desired type is an array of unknown bounds because the variable
has had its bounds deduced since the wrapping expression was created. */
static bool
same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2)
{
while (TREE_CODE (type1) == ARRAY_TYPE
&& TREE_CODE (type2) == ARRAY_TYPE
&& (!TYPE_DOMAIN (type1) || !TYPE_DOMAIN (type2)))
{
type1 = TREE_TYPE (type1);
type2 = TREE_TYPE (type2);
}
return same_type_ignoring_top_level_qualifiers_p (type1, type2);
}
/* A less strict version of fold_indirect_ref_1, which requires cv-quals to
match. We want to be less strict for simple *& folding; if we have a
non-const temporary that we access through a const pointer, that should
......@@ -3108,15 +3125,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_top_level_qualifiers_p (optype, type)
/* Also handle the case where the desired type is an array of unknown
bounds because the variable has had its bounds deduced since the
ADDR_EXPR was created. */
|| (TREE_CODE (type) == ARRAY_TYPE
&& TREE_CODE (optype) == ARRAY_TYPE
&& TYPE_DOMAIN (type) == NULL_TREE
&& same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (optype),
TREE_TYPE (type))))
if (same_type_ignoring_tlq_and_bounds_p (optype, type))
{
tree fop = fold_read_from_constant_string (op);
if (fop)
......@@ -4676,7 +4685,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
conversion. */
return fold (t);
if (tcode == UNARY_PLUS_EXPR)
/* Handle an array's bounds having been deduced after we built
the wrapping expression. */
if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))
r = op;
else if (tcode == UNARY_PLUS_EXPR)
r = fold_convert (TREE_TYPE (t), op);
else
r = fold_build1 (tcode, type, op);
......
......@@ -399,7 +399,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR)
FNDECL_USED_AUTO (in FUNCTION_DECL)
DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE)
REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF, SCOPE_REF)
REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF, SCOPE_REF, VIEW_CONVERT_EXPR)
AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR)
CONSTRUCTOR_MUTABLE_POISON (in CONSTRUCTOR)
OVL_HIDDEN_P (in OVERLOAD)
......@@ -3676,7 +3676,7 @@ struct GTY(()) lang_decl {
of the time in C++14 mode. */
#define REF_PARENTHESIZED_P(NODE) \
TREE_LANG_FLAG_2 (TREE_CHECK3 ((NODE), COMPONENT_REF, INDIRECT_REF, SCOPE_REF))
TREE_LANG_FLAG_2 (TREE_CHECK4 ((NODE), COMPONENT_REF, INDIRECT_REF, SCOPE_REF, VIEW_CONVERT_EXPR))
/* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
constructor call, rather than an ordinary function call. */
......
......@@ -1720,23 +1720,10 @@ force_paren_expr (tree expr)
REF_PARENTHESIZED_P (expr) = true;
else if (processing_template_decl)
expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr);
else if (VAR_P (expr) && DECL_HARD_REGISTER (expr))
/* We can't bind a hard register variable to a reference. */;
else
{
cp_lvalue_kind kind = lvalue_kind (expr);
if ((kind & ~clk_class) != clk_none)
{
tree type = unlowered_expr_type (expr);
bool rval = !!(kind & clk_rvalueref);
type = cp_build_reference_type (type, rval);
/* This inhibits warnings in, eg, cxx_mark_addressable
(c++/60955). */
warning_sentinel s (extra_warnings);
expr = build_static_cast (type, expr, tf_error);
if (expr != error_mark_node)
REF_PARENTHESIZED_P (expr) = true;
}
expr = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr);
REF_PARENTHESIZED_P (expr) = true;
}
return expr;
......@@ -1765,6 +1752,9 @@ maybe_undo_parenthesized_ref (tree t)
}
else if (TREE_CODE (t) == PAREN_EXPR)
t = TREE_OPERAND (t, 0);
else if (TREE_CODE (t) == VIEW_CONVERT_EXPR
&& REF_PARENTHESIZED_P (t))
t = TREE_OPERAND (t, 0);
return t;
}
......
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