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> 2018-06-21 Jason Merrill <jason@redhat.com>
* pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Use TEMPLATE_PARM_DESCENDANTS. * pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Use TEMPLATE_PARM_DESCENDANTS.
......
...@@ -3076,6 +3076,23 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t, ...@@ -3076,6 +3076,23 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
return r; 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 /* 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 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 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) ...@@ -3108,15 +3125,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_top_level_qualifiers_p (optype, type) if (same_type_ignoring_tlq_and_bounds_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))))
{ {
tree fop = fold_read_from_constant_string (op); tree fop = fold_read_from_constant_string (op);
if (fop) if (fop)
...@@ -4676,7 +4685,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, ...@@ -4676,7 +4685,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
conversion. */ conversion. */
return fold (t); 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); r = fold_convert (TREE_TYPE (t), op);
else else
r = fold_build1 (tcode, type, op); r = fold_build1 (tcode, type, op);
......
...@@ -399,7 +399,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; ...@@ -399,7 +399,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR) TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR)
FNDECL_USED_AUTO (in FUNCTION_DECL) FNDECL_USED_AUTO (in FUNCTION_DECL)
DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE) 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) AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR)
CONSTRUCTOR_MUTABLE_POISON (in CONSTRUCTOR) CONSTRUCTOR_MUTABLE_POISON (in CONSTRUCTOR)
OVL_HIDDEN_P (in OVERLOAD) OVL_HIDDEN_P (in OVERLOAD)
...@@ -3676,7 +3676,7 @@ struct GTY(()) lang_decl { ...@@ -3676,7 +3676,7 @@ struct GTY(()) lang_decl {
of the time in C++14 mode. */ of the time in C++14 mode. */
#define REF_PARENTHESIZED_P(NODE) \ #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 /* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
constructor call, rather than an ordinary function call. */ constructor call, rather than an ordinary function call. */
......
...@@ -1720,23 +1720,10 @@ force_paren_expr (tree expr) ...@@ -1720,23 +1720,10 @@ force_paren_expr (tree expr)
REF_PARENTHESIZED_P (expr) = true; REF_PARENTHESIZED_P (expr) = true;
else if (processing_template_decl) else if (processing_template_decl)
expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr); 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 else
{ {
cp_lvalue_kind kind = lvalue_kind (expr); expr = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr);
if ((kind & ~clk_class) != clk_none) REF_PARENTHESIZED_P (expr) = true;
{
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;
}
} }
return expr; return expr;
...@@ -1765,6 +1752,9 @@ maybe_undo_parenthesized_ref (tree t) ...@@ -1765,6 +1752,9 @@ maybe_undo_parenthesized_ref (tree t)
} }
else if (TREE_CODE (t) == PAREN_EXPR) else if (TREE_CODE (t) == PAREN_EXPR)
t = TREE_OPERAND (t, 0); t = TREE_OPERAND (t, 0);
else if (TREE_CODE (t) == VIEW_CONVERT_EXPR
&& REF_PARENTHESIZED_P (t))
t = TREE_OPERAND (t, 0);
return t; 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