https://gcc.gnu.org/g:0ba14502c966d4e8c64bc701d41b0ff9a84ea130
commit r16-9160-g0ba14502c966d4e8c64bc701d41b0ff9a84ea130 Author: Jason Merrill <[email protected]> Date: Tue Jun 23 09:49:36 2026 -0400 c++: ubsan and inherited vptr [PR125745] cp_ubsan_instrument_vptr tried to open-code vfield access and failed to look into the base subobject to find it. We have a function for that. PR c++/125745 gcc/cp/ChangeLog: * cp-ubsan.cc (cp_ubsan_instrument_vptr): Use build_vfield_ref. gcc/testsuite/ChangeLog: * g++.dg/ubsan/vptr-19.C: New test. (cherry picked from commit 88f05f89957383f7b0328e9c558ebb12d1d58f52) Diff: --- gcc/cp/cp-ubsan.cc | 5 +---- gcc/testsuite/g++.dg/ubsan/vptr-19.C | 8 ++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/gcc/cp/cp-ubsan.cc b/gcc/cp/cp-ubsan.cc index 9fc5744ea402..68689c8e36f3 100644 --- a/gcc/cp/cp-ubsan.cc +++ b/gcc/cp/cp-ubsan.cc @@ -69,10 +69,7 @@ cp_ubsan_instrument_vptr (location_t loc, tree op, tree type, bool is_addr, if (!is_addr) op = build_fold_addr_expr_loc (loc, op); op = save_expr (op); - tree vptr = fold_build3_loc (loc, COMPONENT_REF, - TREE_TYPE (TYPE_VFIELD (type)), - build_fold_indirect_ref_loc (loc, op), - TYPE_VFIELD (type), NULL_TREE); + tree vptr = build_vfield_ref (build_fold_indirect_ref_loc (loc, op), type); vptr = fold_convert_loc (loc, pointer_sized_int_node, vptr); vptr = fold_convert_loc (loc, uint64_type_node, vptr); if (ckind == UBSAN_DOWNCAST_POINTER) diff --git a/gcc/testsuite/g++.dg/ubsan/vptr-19.C b/gcc/testsuite/g++.dg/ubsan/vptr-19.C new file mode 100644 index 000000000000..25ad7ff51774 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/vptr-19.C @@ -0,0 +1,8 @@ +// PR c++/125745 +// { dg-do compile { target c++11 } } +// { dg-additional-options -fsanitize=undefined } + +struct A { virtual void foo (); }; +struct B : A { constexpr int foo () const { return 42; } }; +constexpr B x; +struct C { int i; C () : i (x.foo ()) {} };
