diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3fb9100e0237..23fb6ad0ff54 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2020-04-08 Jakub Jelinek + + PR c++/94325 + * decl.c (begin_destructor_body): For CLASSTYPE_VBASECLASSES class + dtors, if CLASSTYPE_PRIMARY_BINFO is non-NULL, but not BINFO_VIRTUAL_P, + look at CLASSTYPE_PRIMARY_BINFO of its BINFO_TYPE if it is not + BINFO_VIRTUAL_P, and so on. + 2020-04-08 Marek Polacek PR c++/94478 - ICE with defaulted comparison operator diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a127734af693..0ea4b320d865 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -16663,14 +16663,20 @@ begin_destructor_body (void) /* If the vptr is shared with some virtual nearly empty base, don't clear it if not in charge, the dtor of the virtual nearly empty base will do that later. */ - if (CLASSTYPE_VBASECLASSES (current_class_type) - && CLASSTYPE_PRIMARY_BINFO (current_class_type) - && BINFO_VIRTUAL_P - (CLASSTYPE_PRIMARY_BINFO (current_class_type))) + if (CLASSTYPE_VBASECLASSES (current_class_type)) { - stmt = convert_to_void (stmt, ICV_STATEMENT, - tf_warning_or_error); - stmt = build_if_in_charge (stmt); + tree c = current_class_type; + while (CLASSTYPE_PRIMARY_BINFO (c)) + { + if (BINFO_VIRTUAL_P (CLASSTYPE_PRIMARY_BINFO (c))) + { + stmt = convert_to_void (stmt, ICV_STATEMENT, + tf_warning_or_error); + stmt = build_if_in_charge (stmt); + break; + } + c = BINFO_TYPE (CLASSTYPE_PRIMARY_BINFO (c)); + } } finish_decl_cleanup (NULL_TREE, stmt); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 278330f528f2..9627b2900fab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-04-08 Jakub Jelinek + + PR c++/94325 + * g++.dg/ubsan/vptr-15.C: New test. + 2020-04-08 Marek Polacek PR c++/94478 - ICE with defaulted comparison operator diff --git a/gcc/testsuite/g++.dg/ubsan/vptr-15.C b/gcc/testsuite/g++.dg/ubsan/vptr-15.C new file mode 100644 index 000000000000..f6f36a58bab7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/vptr-15.C @@ -0,0 +1,14 @@ +// PR c++/94325 +// { dg-do run { target c++11 } } +// { dg-options "-fsanitize=vptr -fno-sanitize-recover=vptr" } + +struct A { virtual ~A () = default; }; +struct B : public virtual A {}; +struct C : public B {}; +struct D : public C {}; + +int +main () +{ + D a; +}