* 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
+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.
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
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)
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);
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)
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. */
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;
}
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;
}