aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2020-12-02 14:33:13 -0500
committerMarek Polacek <polacek@redhat.com>2020-12-08 17:26:37 -0500
commit0221c656bbe5b4ab54e784df3b109c60cb27e5b6 (patch)
tree96822a349ac389e06496aea1a0f54ec4eee2e6d9 /gcc/cp
parent5ea350d1d7edf8afaae9e6723cda535c9eaa7562 (diff)
downloadgcc-0221c656bbe5b4ab54e784df3b109c60cb27e5b6.zip
gcc-0221c656bbe5b4ab54e784df3b109c60cb27e5b6.tar.gz
gcc-0221c656bbe5b4ab54e784df3b109c60cb27e5b6.tar.bz2
c++: ICE with -fsanitize=vptr and constexpr dynamic_cast [PR98103]
-fsanitize=vptr initializes all vtable pointers to null so that it can catch invalid calls; see cp_ubsan_maybe_initialize_vtbl_ptrs. That means that evaluating a vtable reference can produce a null pointer in this mode, so cxx_eval_dynamic_cast_fn should check that and give and error. gcc/cp/ChangeLog: PR c++/98103 * constexpr.c (cxx_eval_dynamic_cast_fn): If the evaluating of vtable yields a null pointer, give an error and return. Use objtype. gcc/testsuite/ChangeLog: PR c++/98103 * g++.dg/ubsan/vptr-18.C: New test.
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/constexpr.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 2ef6de8..b6f3e6e 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1998,11 +1998,20 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call,
to the object under construction or destruction, this object is
considered to be a most derived object that has the type of the
constructor or destructor's class. */
- tree vtable = build_vfield_ref (obj, TREE_TYPE (obj));
+ tree vtable = build_vfield_ref (obj, objtype);
vtable = cxx_eval_constant_expression (ctx, vtable, /*lval*/false,
non_constant_p, overflow_p);
if (*non_constant_p)
return call;
+ /* With -fsanitize=vptr, we initialize all vtable pointers to null,
+ so it's possible that we got a null pointer now. */
+ if (integer_zerop (vtable))
+ {
+ if (!ctx->quiet)
+ error_at (loc, "virtual table pointer is used uninitialized");
+ *non_constant_p = true;
+ return integer_zero_node;
+ }
/* VTABLE will be &_ZTV1A + 16 or similar, get _ZTV1A. */
vtable = extract_obj_from_addr_offset (vtable);
const tree mdtype = DECL_CONTEXT (vtable);