Fix various latent issues revealed by P0732 work.
The initialized_type hunk fixes handling of void AGGR_INIT_EXPRs that call a non-constructor; an AGGR_INIT_EXPR can have void type if its initialization semantics are more complicated than just expanding the call. The cxx_eval_vec_init_1 hunk corrects AGGR_INIT_EXPRs that were nonsensically built to initialize an object of void type. And the build_aggr_init_expr hunk makes sure we don't do that again. The ocp_convert and cxx_eval_outermost_constant_expr hunks deal with making sure that a constant CONSTRUCTOR has the right type. * 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. From-SVN: r265788
This commit is contained in:
parent
c24c8a4b00
commit
5dab8b11c4
@ -1,5 +1,12 @@
|
||||
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.
|
||||
|
@ -2778,8 +2778,10 @@ initialized_type (tree t)
|
||||
{
|
||||
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);
|
||||
@ -2787,7 +2789,9 @@ initialized_type (tree 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.
|
||||
@ -3000,7 +3004,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
|
||||
&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;
|
||||
}
|
||||
|
||||
@ -5089,7 +5093,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
|
||||
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)
|
||||
@ -5097,18 +5101,18 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
|
||||
|
||||
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,
|
||||
|
10
gcc/cp/cvt.c
10
gcc/cp/cvt.c
@ -725,7 +725,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
|
||||
/* 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
|
||||
@ -743,9 +744,16 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
|
||||
{
|
||||
/* 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
|
||||
|
@ -576,6 +576,8 @@ build_aggr_init_expr (tree type, tree init)
|
||||
tree rval;
|
||||
int is_ctor;
|
||||
|
||||
gcc_assert (!VOID_TYPE_P (type));
|
||||
|
||||
/* Don't build AGGR_INIT_EXPR in a template. */
|
||||
if (processing_template_decl)
|
||||
return init;
|
||||
|
Loading…
Reference in New Issue
Block a user