diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-12-03 09:19:04 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-12-03 09:19:04 +0100 |
commit | 5558a0da3248524d5fc081dc0580ab4f9e6eb0e2 (patch) | |
tree | ea748b6074ebac645335ae075a76ac871e132270 /gcc/cp | |
parent | 3d109462bdd666cc5ce2d0b6b0c3b7a3c19b0b4c (diff) | |
download | gcc-5558a0da3248524d5fc081dc0580ab4f9e6eb0e2.zip gcc-5558a0da3248524d5fc081dc0580ab4f9e6eb0e2.tar.gz gcc-5558a0da3248524d5fc081dc0580ab4f9e6eb0e2.tar.bz2 |
re PR c++/92695 (P1064R0 - virtual constexpr fails if object taken from array)
PR c++/92695
* constexpr.c (cxx_bind_parameters_in_call): For virtual calls,
adjust the first argument to point to the derived object rather
than its base.
* g++.dg/cpp2a/constexpr-virtual14.C: New test.
From-SVN: r278921
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 20 |
2 files changed, 27 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9ca25ae..1565d72 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-12-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/92695 + * constexpr.c (cxx_bind_parameters_in_call): For virtual calls, + adjust the first argument to point to the derived object rather + than its base. + 2019-12-02 Jakub Jelinek <jakub@redhat.com> PR c++/92695 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index cc3ef10..3911820 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1441,6 +1441,26 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, arg = adjust_temp_type (type, arg); if (!TREE_CONSTANT (arg)) *non_constant_args = true; + /* For virtual calls, adjust the this argument, so that it is + the object on which the method is called, rather than + one of its bases. */ + if (i == 0 && DECL_VIRTUAL_P (fun)) + { + tree addr = arg; + STRIP_NOPS (addr); + if (TREE_CODE (addr) == ADDR_EXPR) + { + tree obj = TREE_OPERAND (addr, 0); + while (TREE_CODE (obj) == COMPONENT_REF + && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1)) + && !same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (obj), DECL_CONTEXT (fun))) + obj = TREE_OPERAND (obj, 0); + if (obj != TREE_OPERAND (addr, 0)) + arg = build_fold_addr_expr_with_type (obj, + TREE_TYPE (arg)); + } + } TREE_VEC_ELT (binds, i) = arg; } parms = TREE_CHAIN (parms); |