aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2017-11-15 08:01:01 +0100
committerMartin Liska <marxin@gcc.gnu.org>2017-11-15 07:01:01 +0000
commit896f6b3dfa6fb337109f97bed8d74c1e030c965e (patch)
treecf440ff8306354ca1233cc796105d1c100583a0d /gcc/cp
parent2a6fc98713d6f9b98d186a52ffc3160819bd580e (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/decl.c21
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. */