2018-11-04 Jason Merrill <jason@redhat.com>
+ * cvt.c (ocp_convert): Don't wrap a CONSTRUCTOR in a NOP_EXPR.
+ * constexpr.c (initialized_type): Fix AGGR_INIT_EXPR handling.
+ (cxx_eval_vec_init_1): Correct type of AGGR_INIT_EXPR.
+ (cxx_eval_outermost_constant_expr): Make sure a CONSTRUCTOR has the
+ right type. Don't wrap a CONSTRUCTOR if one was passed in.
+ * tree.c (build_aggr_init_expr): Check for void.
+
PR c++/60503 - wrong lambda attribute syntax.
* parser.c (cp_parser_lambda_declarator_opt): Fix attribute
handling.
{
if (TYPE_P (t))
return t;
- tree type = cv_unqualified (TREE_TYPE (t));
- if (TREE_CODE (t) == CALL_EXPR || TREE_CODE (t) == AGGR_INIT_EXPR)
+ tree type = TREE_TYPE (t);
+ if (!VOID_TYPE_P (type))
+ /* No need to look deeper. */;
+ else if (TREE_CODE (t) == CALL_EXPR)
{
/* A constructor call has void type, so we need to look deeper. */
tree fn = get_function_named_in_call (t);
&& DECL_CXX_CONSTRUCTOR_P (fn))
type = DECL_CONTEXT (fn);
}
- return type;
+ else if (TREE_CODE (t) == AGGR_INIT_EXPR)
+ type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t));
+ return cv_unqualified (type);
}
/* We're about to initialize element INDEX of an array or class from VALUE.
&argvec, elttype, LOOKUP_NORMAL,
complain);
release_tree_vector (argvec);
- init = build_aggr_init_expr (TREE_TYPE (init), init);
+ init = build_aggr_init_expr (elttype, init);
pre_init = true;
}
r = build_nop (TREE_TYPE (r), r);
TREE_CONSTANT (r) = false;
}
- else if (non_constant_p || r == t)
+ else if (non_constant_p)
return t;
if (should_unshare)
if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
{
+ r = adjust_temp_type (type, r);
if (TREE_CODE (t) == TARGET_EXPR
&& TARGET_EXPR_INITIAL (t) == r)
return t;
- else
+ else if (TREE_CODE (t) != CONSTRUCTOR)
{
r = get_target_expr (r);
TREE_CONSTANT (r) = true;
- return r;
}
}
- else
- return r;
+
+ return r;
}
/* Returns true if T is a valid subexpression of a constant expression,
/* We need a new temporary; don't take this shortcut. */;
else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (e)))
{
- if (same_type_p (type, TREE_TYPE (e)))
+ tree etype = TREE_TYPE (e);
+ if (same_type_p (type, etype))
/* The call to fold will not always remove the NOP_EXPR as
might be expected, since if one of the types is a typedef;
the comparison in fold is just equality of pointers, not a
{
/* Don't build a NOP_EXPR of class type. Instead, change the
type of the temporary. */
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype));
TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
return e;
}
+ else if (TREE_CODE (e) == CONSTRUCTOR)
+ {
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype));
+ TREE_TYPE (e) = type;
+ return e;
+ }
else
{
/* We shouldn't be treating objects of ADDRESSABLE type as