aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2018-12-11 21:37:53 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-12-11 21:37:53 +0100
commit582d2481f7380441c345bf1dfe698f90f34dd6cf (patch)
treed4a98b7a3f984eb5a9776ad9a0437508358bea3e /gcc/cp/constexpr.c
parent3c0517a6531112d2dec16d18cdabb1513d387b7a (diff)
downloadgcc-582d2481f7380441c345bf1dfe698f90f34dd6cf.zip
gcc-582d2481f7380441c345bf1dfe698f90f34dd6cf.tar.gz
gcc-582d2481f7380441c345bf1dfe698f90f34dd6cf.tar.bz2
re PR c++/87861 (ICE in output_constructor_regular_field, at varasm.c:5165)
PR c++/87861 * class.c (build_vtbl_initializer): For TARGET_VTABLE_USES_DESCRIPTORS bump index for each added word. * constexpr.c (find_array_ctor_elt): Add forward declaration. (cxx_eval_call_expression): Handle TARGET_VTABLE_USES_DESCRIPTORS vtable calls. (cxx_eval_constant_expression) <case OBJ_TYPE_REF>: Divide token by TARGET_VTABLE_USES_DESCRIPTORS if non-zero. From-SVN: r267032
Diffstat (limited to 'gcc/cp/constexpr.c')
-rw-r--r--gcc/cp/constexpr.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 44db380..96326c3 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -41,6 +41,9 @@ do { \
return t; \
} while (0)
+static HOST_WIDE_INT find_array_ctor_elt (tree ary, tree dindex,
+ bool insert = false);
+
/* Returns true iff FUN is an instantiation of a constexpr function
template or a defaulted constexpr function. */
@@ -1516,6 +1519,36 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
STRIP_NOPS (fun);
if (TREE_CODE (fun) == ADDR_EXPR)
fun = TREE_OPERAND (fun, 0);
+ /* For TARGET_VTABLE_USES_DESCRIPTORS targets, there is no
+ indirection, the called expression is a pointer into the
+ virtual table which should contain FDESC_EXPR. Extract the
+ FUNCTION_DECL from there. */
+ else if (TARGET_VTABLE_USES_DESCRIPTORS
+ && TREE_CODE (fun) == POINTER_PLUS_EXPR
+ && TREE_CODE (TREE_OPERAND (fun, 0)) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fun, 1)) == INTEGER_CST)
+ {
+ tree d = TREE_OPERAND (TREE_OPERAND (fun, 0), 0);
+ if (VAR_P (d)
+ && DECL_VTABLE_OR_VTT_P (d)
+ && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE
+ && TREE_TYPE (TREE_TYPE (d)) == vtable_entry_type
+ && DECL_INITIAL (d)
+ && TREE_CODE (DECL_INITIAL (d)) == CONSTRUCTOR)
+ {
+ tree i = int_const_binop (TRUNC_DIV_EXPR, TREE_OPERAND (fun, 1),
+ TYPE_SIZE_UNIT (vtable_entry_type));
+ HOST_WIDE_INT idx = find_array_ctor_elt (DECL_INITIAL (d), i);
+ if (idx >= 0)
+ {
+ tree fdesc
+ = (*CONSTRUCTOR_ELTS (DECL_INITIAL (d)))[idx].value;
+ if (TREE_CODE (fdesc) == FDESC_EXPR
+ && integer_zerop (TREE_OPERAND (fdesc, 1)))
+ fun = TREE_OPERAND (fdesc, 0);
+ }
+ }
+ }
}
if (TREE_CODE (fun) != FUNCTION_DECL)
{
@@ -2240,7 +2273,7 @@ array_index_cmp (tree key, tree index)
if none. If INSERT is true, insert a matching element rather than fail. */
static HOST_WIDE_INT
-find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
+find_array_ctor_elt (tree ary, tree dindex, bool insert)
{
if (tree_int_cst_sgn (dindex) < 0)
return -1;
@@ -4834,6 +4867,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* Find the function decl in the virtual functions list. TOKEN is
the DECL_VINDEX that says which function we're looking for. */
tree virtuals = BINFO_VIRTUALS (TYPE_BINFO (objtype));
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ token /= MAX (TARGET_VTABLE_USES_DESCRIPTORS, 1);
r = TREE_VALUE (chain_index (token, virtuals));
break;
}