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
This commit is contained in:
parent
73607ff9ec
commit
e4511ca2e9
4 changed files with 41 additions and 27 deletions
|
@ -1,3 +1,14 @@
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue