c++: vptr ubsan and derived class [PR95311].

We weren't able to find OBJ_TYPE_REF_OBJECT walking through
OBJ_TYPE_REF_EXPR because we had folded away the ADDR_EXPR.

gcc/cp/ChangeLog:

	PR c++/95311
	PR c++/95221
	* class.c (build_vfn_ref): Don't fold the INDIRECT_REF.

gcc/testsuite/ChangeLog:

	PR c++/95311
	* g++.dg/ubsan/vptr-16.C: New test.
This commit is contained in:
Jason Merrill 2020-05-29 11:59:33 -04:00
parent 83c34c4452
commit 8e915901de
2 changed files with 20 additions and 2 deletions

View File

@ -729,9 +729,13 @@ build_vtbl_ref (tree instance, tree idx)
tree
build_vfn_ref (tree instance_ptr, tree idx)
{
tree aref;
tree obtype = TREE_TYPE (TREE_TYPE (instance_ptr));
aref = build_vtbl_ref (cp_build_fold_indirect_ref (instance_ptr), idx);
/* 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);
/* When using function descriptors, the address of the
vtable entry is treated as a function pointer. */

View File

@ -0,0 +1,14 @@
// PR c++/95311
// { dg-additional-options -fsanitize=undefined }
class a {
virtual long b() const;
};
class c : a {
public:
long b() const;
};
class d : c {
long e();
};
long d::e() { b(); return 0; }