backport: re PR c++/92695 (P1064R0 - virtual constexpr fails if object taken from array)
Backported from mainline 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. * g++.dg/cpp2a/constexpr-virtual14.C: New test. From-SVN: r279664
This commit is contained in:
parent
d9c7be4ce3
commit
ae1b211b58
@ -1,6 +1,13 @@
|
||||
2019-12-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
Backported from mainline
|
||||
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
|
||||
|
@ -1419,6 +1419,28 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
*p = build_tree_list (parms, arg);
|
||||
p = &TREE_CHAIN (*p);
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
2019-12-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
Backported from mainline
|
||||
2019-12-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/92695
|
||||
* g++.dg/cpp2a/constexpr-virtual14.C: New test.
|
||||
|
||||
2019-12-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/92695
|
||||
|
27
gcc/testsuite/g++.dg/cpp2a/constexpr-virtual14.C
Normal file
27
gcc/testsuite/g++.dg/cpp2a/constexpr-virtual14.C
Normal file
@ -0,0 +1,27 @@
|
||||
// PR c++/92695
|
||||
// { dg-do compile { target c++2a } }
|
||||
|
||||
struct A {
|
||||
virtual int get () = 0;
|
||||
virtual int set (A *o) = 0;
|
||||
};
|
||||
struct B : A {
|
||||
constexpr int get () override { return 10; }
|
||||
constexpr int set (A *o) override { a = o; return 20; }
|
||||
A *a {};
|
||||
};
|
||||
constexpr auto addressof = [] (A &n) { return &n; };
|
||||
struct C {
|
||||
B b;
|
||||
A *c { addressof (b) };
|
||||
constexpr int add () { return c->set (addressof (b)); }
|
||||
};
|
||||
struct D {
|
||||
B b[2];
|
||||
A *c { addressof (b[0]) };
|
||||
constexpr int add () { return c->set (addressof (b[0])); }
|
||||
};
|
||||
template <typename T>
|
||||
constexpr int get () { T f; return f.add (); }
|
||||
static_assert (get<C> () == 20);
|
||||
static_assert (get<D> () == 20);
|
Loading…
Reference in New Issue
Block a user