c++: vptr ubsan and object of known type [PR95466]
Another case where we can't find the OBJ_TYPE_REF_OBJECT in the OBJ_TYPE_REF_EXPR. So let's just evaluate the sanitize call first. gcc/cp/ChangeLog: PR c++/95466 PR c++/95311 PR c++/95221 * class.c (build_vfn_ref): Revert 95311 change. * cp-ubsan.c (cp_ubsan_maybe_instrument_member_call): Build a COMPOUND_EXPR. gcc/testsuite/ChangeLog: PR c++/95466 * g++.dg/ubsan/vptr-17.C: New test.
This commit is contained in:
parent
832c1192eb
commit
172f2c42a1
3 changed files with 25 additions and 15 deletions
|
@ -729,13 +729,9 @@ build_vtbl_ref (tree instance, tree idx)
|
|||
tree
|
||||
build_vfn_ref (tree instance_ptr, tree idx)
|
||||
{
|
||||
tree obtype = TREE_TYPE (TREE_TYPE (instance_ptr));
|
||||
tree aref;
|
||||
|
||||
/* Leave the INDIRECT_REF unfolded so cp_ubsan_maybe_instrument_member_call
|
||||
can find instance_ptr. */
|
||||
tree ind = build1 (INDIRECT_REF, obtype, instance_ptr);
|
||||
|
||||
tree aref = build_vtbl_ref (ind, idx);
|
||||
aref = build_vtbl_ref (cp_build_fold_indirect_ref (instance_ptr), idx);
|
||||
|
||||
/* When using function descriptors, the address of the
|
||||
vtable entry is treated as a function pointer. */
|
||||
|
|
|
@ -125,16 +125,11 @@ cp_ubsan_maybe_instrument_member_call (tree stmt)
|
|||
{
|
||||
/* Virtual function call: Sanitize the use of the object pointer in the
|
||||
OBJ_TYPE_REF, since the vtable reference will SEGV otherwise (95221).
|
||||
OBJ_TYPE_REF_EXPR is ptr->vptr[N] and OBJ_TYPE_REF_OBJECT is ptr. */
|
||||
OBJ_TYPE_REF_EXPR is ptr->vptr[N] and OBJ_TYPE_REF_OBJECT is ptr. But
|
||||
we can't be sure of finding OBJ_TYPE_REF_OBJECT in OBJ_TYPE_REF_EXPR
|
||||
if the latter has been optimized, so we use a COMPOUND_EXPR below. */
|
||||
opp = &OBJ_TYPE_REF_EXPR (fn);
|
||||
op = OBJ_TYPE_REF_OBJECT (fn);
|
||||
while (*opp != op)
|
||||
{
|
||||
if (TREE_CODE (*opp) == COMPOUND_EXPR)
|
||||
opp = &TREE_OPERAND (*opp, 1);
|
||||
else
|
||||
opp = &TREE_OPERAND (*opp, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -150,7 +145,11 @@ cp_ubsan_maybe_instrument_member_call (tree stmt)
|
|||
op = cp_ubsan_maybe_instrument_vptr (EXPR_LOCATION (stmt), op,
|
||||
TREE_TYPE (TREE_TYPE (op)),
|
||||
true, UBSAN_MEMBER_CALL);
|
||||
if (op)
|
||||
if (!op)
|
||||
/* No change. */;
|
||||
else if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
|
||||
*opp = cp_build_compound_expr (op, *opp, tf_none);
|
||||
else
|
||||
*opp = op;
|
||||
}
|
||||
|
||||
|
|
15
gcc/testsuite/g++.dg/ubsan/vptr-17.C
Normal file
15
gcc/testsuite/g++.dg/ubsan/vptr-17.C
Normal file
|
@ -0,0 +1,15 @@
|
|||
// PR c++/95466
|
||||
// { dg-additional-options -fsanitize=vptr }
|
||||
|
||||
class A {
|
||||
virtual void m_fn1();
|
||||
};
|
||||
class C {
|
||||
public:
|
||||
virtual void m_fn2();
|
||||
};
|
||||
class B : A, public C {};
|
||||
int main() {
|
||||
B b;
|
||||
static_cast<C *>(&b)->m_fn2();
|
||||
}
|
Loading…
Add table
Reference in a new issue