From d66ab7d12bb632c3de947f535d189275209a3915 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 29 Aug 2018 23:43:18 +0200 Subject: [PATCH] re PR sanitizer/87095 (UndefinedBehaviorSanitizer vptr false positive with virtual inheritance only with -fno-sanitize-recover) PR c++/87095 * decl.c (begin_destructor_body): If current_class_type has virtual bases and the primary base is nearly empty virtual base, voidify clearing of vptr and make it conditional on in-charge argument. * g++.dg/ubsan/vptr-13.C: New test. From-SVN: r263967 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/decl.c | 12 ++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/ubsan/vptr-13.C | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ubsan/vptr-13.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6ed074eea1a..6ecd48dfac8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2018-08-29 Jakub Jelinek + + PR c++/87095 + * decl.c (begin_destructor_body): If current_class_type has + virtual bases and the primary base is nearly empty virtual base, + voidify clearing of vptr and make it conditional on in-charge + argument. + 2018-08-29 Paolo Carlini PR c++/85265 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 7fee3da1f49..c6711f74177 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -15698,6 +15698,18 @@ begin_destructor_body (void) tree stmt = cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR, vtbl, tf_warning_or_error); + /* 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))) + { + stmt = convert_to_void (stmt, ICV_STATEMENT, + tf_warning_or_error); + stmt = build_if_in_charge (stmt); + } finish_decl_cleanup (NULL_TREE, stmt); } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 78bbd7f31e5..e38dab2f8ab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-08-29 Jakub Jelinek + + PR c++/87095 + * g++.dg/ubsan/vptr-13.C: New test. + 2018-08-29 Paolo Carlini PR c++/85265 diff --git a/gcc/testsuite/g++.dg/ubsan/vptr-13.C b/gcc/testsuite/g++.dg/ubsan/vptr-13.C new file mode 100644 index 00000000000..345581fd9d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/vptr-13.C @@ -0,0 +1,19 @@ +// PR c++/87095 +// { dg-do run } +// { dg-options "-fsanitize=vptr -fno-sanitize-recover=vptr" } + +struct A +{ + virtual ~A () {} +}; + +struct B : virtual A {}; + +struct C : B {}; + +int +main () +{ + C c; + return 0; +} -- 2.30.2