aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-11-05 02:46:57 -0500
committerJason Merrill <jason@gcc.gnu.org>2018-11-05 02:46:57 -0500
commit5dab8b11c41fe72ea606c38884f7730bd2aeafdc (patch)
tree93c5972f6c8b0ac891b9a3d2e0afdc8eda67bf8e /gcc/cp/constexpr.c
parentc24c8a4b003f81734c2a94e0980008c2c24659d9 (diff)
downloadgcc-5dab8b11c41fe72ea606c38884f7730bd2aeafdc.zip
gcc-5dab8b11c41fe72ea606c38884f7730bd2aeafdc.tar.gz
gcc-5dab8b11c41fe72ea606c38884f7730bd2aeafdc.tar.bz2
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
Diffstat (limited to 'gcc/cp/constexpr.c')
-rw-r--r--gcc/cp/constexpr.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 7692b17..4fb1ba5 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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,