diff options
author | Martin Liska <mliska@suse.cz> | 2017-11-15 08:01:01 +0100 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2017-11-15 07:01:01 +0000 |
commit | 896f6b3dfa6fb337109f97bed8d74c1e030c965e (patch) | |
tree | cf440ff8306354ca1233cc796105d1c100583a0d /gcc/cp | |
parent | 2a6fc98713d6f9b98d186a52ffc3160819bd580e (diff) | |
download | gcc-896f6b3dfa6fb337109f97bed8d74c1e030c965e.zip gcc-896f6b3dfa6fb337109f97bed8d74c1e030c965e.tar.gz gcc-896f6b3dfa6fb337109f97bed8d74c1e030c965e.tar.bz2 |
Zero vptr in dtor for -fsanitize=vptr.
2017-11-15 Martin Liska <mliska@suse.cz>
* decl.c (begin_destructor_body): In case of VPTR sanitization
(with disabled recovery), zero vptr in order to catch virtual calls
after lifetime of an object.
2017-11-15 Martin Liska <mliska@suse.cz>
* g++.dg/ubsan/vptr-12.C: New test.
From-SVN: r254754
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 21 |
2 files changed, 26 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8ba5b78..578299e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-11-15 Martin Liska <mliska@suse.cz> + + * decl.c (begin_destructor_body): In case of VPTR sanitization + (with disabled recovery), zero vptr in order to catch virtual calls + after lifetime of an object. + 2017-11-14 Jason Merrill <jason@redhat.com> Use GTY((cache)) on some hash tables. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c4eb28d..041893d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -15246,7 +15246,26 @@ begin_destructor_body (void) if (flag_lifetime_dse /* Clobbering an empty base is harmful if it overlays real data. */ && !is_empty_class (current_class_type)) - finish_decl_cleanup (NULL_TREE, build_clobber_this ()); + { + if (sanitize_flags_p (SANITIZE_VPTR) + && (flag_sanitize_recover & SANITIZE_VPTR) == 0 + && TYPE_CONTAINS_VPTR_P (current_class_type)) + { + tree binfo = TYPE_BINFO (current_class_type); + tree ref + = cp_build_indirect_ref (current_class_ptr, RO_NULL, + tf_warning_or_error); + + tree vtbl_ptr = build_vfield_ref (ref, TREE_TYPE (binfo)); + tree vtbl = build_zero_cst (TREE_TYPE (vtbl_ptr)); + tree stmt = cp_build_modify_expr (input_location, vtbl_ptr, + NOP_EXPR, vtbl, + tf_warning_or_error); + finish_decl_cleanup (NULL_TREE, stmt); + } + else + finish_decl_cleanup (NULL_TREE, build_clobber_this ()); + } /* And insert cleanups for our bases and members so that they will be properly destroyed if we throw. */ |