aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-05-04 10:06:40 -0700
committerNathan Sidwell <nathan@acm.org>2020-05-04 10:08:13 -0700
commite6b31fc717207565f144aaefa608344789221f07 (patch)
tree0e4e6a9f0477e50311c78b9be6c4a1af3a0b2f10
parentbb6ce5422066b434f51f6475335788541fd82543 (diff)
downloadgcc-e6b31fc717207565f144aaefa608344789221f07.zip
gcc-e6b31fc717207565f144aaefa608344789221f07.tar.gz
gcc-e6b31fc717207565f144aaefa608344789221f07.tar.bz2
libstdc++: Avoid negating a size_t [pr 94747]
Although the code here is well formed, it doesn't show intent well. The reason checkers trigger on this is that it is a cause of real bugs. So, negate a ptrdiff_t instead. * libsupc++/dyncast.cc (__dynamic_cast): Cast offsetof to ptrdiff_t before negation, to show intent more clearly.
-rw-r--r--libstdc++-v3/ChangeLog6
-rw-r--r--libstdc++-v3/libsupc++/dyncast.cc11
2 files changed, 12 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0624bb7..739ab9e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,9 @@
+2020-05-04 Nathan Sidwell <nathan@acm.org>
+
+ PR libstdc++/94747
+ * libsupc++/dyncast.cc (__dynamic_cast): Cast offsetof to
+ ptrdiff_t before negation, to show intent more clearly.
+
2020-05-04 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/94936
diff --git a/libstdc++-v3/libsupc++/dyncast.cc b/libstdc++-v3/libsupc++/dyncast.cc
index 1254471..7a5f483 100644
--- a/libstdc++-v3/libsupc++/dyncast.cc
+++ b/libstdc++-v3/libsupc++/dyncast.cc
@@ -49,8 +49,8 @@ __dynamic_cast (const void *src_ptr, // object started from
{
const void *vtable = *static_cast <const void *const *> (src_ptr);
const vtable_prefix *prefix =
- adjust_pointer <vtable_prefix> (vtable,
- -offsetof (vtable_prefix, origin));
+ (adjust_pointer <vtable_prefix>
+ (vtable, -ptrdiff_t (offsetof (vtable_prefix, origin))));
const void *whole_ptr =
adjust_pointer <void> (src_ptr, prefix->whole_object);
const __class_type_info *whole_type = prefix->whole_type;
@@ -63,8 +63,8 @@ __dynamic_cast (const void *src_ptr, // object started from
// segfault later trying to use a vbase offset that doesn't exist.
const void *whole_vtable = *static_cast <const void *const *> (whole_ptr);
const vtable_prefix *whole_prefix =
- adjust_pointer <vtable_prefix> (whole_vtable,
- -offsetof (vtable_prefix, origin));
+ (adjust_pointer <vtable_prefix>
+ (whole_vtable, -ptrdiff_t (offsetof (vtable_prefix, origin))));
if (whole_prefix->whole_type != whole_type)
return NULL;
@@ -75,7 +75,8 @@ __dynamic_cast (const void *src_ptr, // object started from
if (contained_public_p (result.dst2src))
// Src is known to be a public base of dst.
return const_cast <void *> (result.dst_ptr);
- if (contained_public_p (__class_type_info::__sub_kind (result.whole2src & result.whole2dst)))
+ if (contained_public_p (__class_type_info::__sub_kind
+ (result.whole2src & result.whole2dst)))
// Both src and dst are known to be public bases of whole. Found a valid
// cross cast.
return const_cast <void *> (result.dst_ptr);