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 ()) {} };

Reply via email to