mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-04 15:30:14 +08:00
re PR sanitizer/64632 (runtime error: member call on address 0x0000004318a8 which does not point to an object of type 'ios_base')
PR sanitizer/64632 * ubsan/ubsan_type_hash.cc: Cherry pick upstream r224972. * g++.dg/ubsan/pr64632.C: New test. From-SVN: r219912
This commit is contained in:
parent
befb1f36a7
commit
3ea3641880
@ -1,5 +1,8 @@
|
||||
2015-01-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR sanitizer/64632
|
||||
* g++.dg/ubsan/pr64632.C: New test.
|
||||
|
||||
PR debug/64663
|
||||
* gcc.dg/pr64663.c: New test.
|
||||
|
||||
|
23
gcc/testsuite/g++.dg/ubsan/pr64632.C
Normal file
23
gcc/testsuite/g++.dg/ubsan/pr64632.C
Normal file
@ -0,0 +1,23 @@
|
||||
// PR sanitizer/64632
|
||||
// { dg-do run }
|
||||
// { dg-options "-fsanitize=vptr -fno-sanitize-recover=vptr" }
|
||||
|
||||
struct S
|
||||
{
|
||||
S () : a(0) {}
|
||||
int a;
|
||||
int f () { return a; }
|
||||
virtual int v () { return 0; }
|
||||
};
|
||||
|
||||
struct X : virtual S
|
||||
{
|
||||
int v () { return 2; }
|
||||
};
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
X x;
|
||||
return x.f ();
|
||||
}
|
@ -1,3 +1,8 @@
|
||||
2015-01-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR sanitizer/64632
|
||||
* ubsan/ubsan_type_hash.cc: Cherry pick upstream r224972.
|
||||
|
||||
2015-01-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR sanitizer/64435
|
||||
|
@ -113,8 +113,7 @@ __ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize];
|
||||
|
||||
/// \brief Determine whether \p Derived has a \p Base base class subobject at
|
||||
/// offset \p Offset.
|
||||
static bool isDerivedFromAtOffset(sptr Object,
|
||||
const abi::__class_type_info *Derived,
|
||||
static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
|
||||
const abi::__class_type_info *Base,
|
||||
sptr Offset) {
|
||||
if (Derived->__type_name == Base->__type_name)
|
||||
@ -122,7 +121,7 @@ static bool isDerivedFromAtOffset(sptr Object,
|
||||
|
||||
if (const abi::__si_class_type_info *SI =
|
||||
dynamic_cast<const abi::__si_class_type_info*>(Derived))
|
||||
return isDerivedFromAtOffset(Object, SI->__base_type, Base, Offset);
|
||||
return isDerivedFromAtOffset(SI->__base_type, Base, Offset);
|
||||
|
||||
const abi::__vmi_class_type_info *VTI =
|
||||
dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
|
||||
@ -137,13 +136,13 @@ static bool isDerivedFromAtOffset(sptr Object,
|
||||
sptr OffsetHere = VTI->base_info[base].__offset_flags >>
|
||||
abi::__base_class_type_info::__offset_shift;
|
||||
if (VTI->base_info[base].__offset_flags &
|
||||
abi::__base_class_type_info::__virtual_mask) {
|
||||
sptr VTable = *reinterpret_cast<const sptr *>(Object);
|
||||
OffsetHere = *reinterpret_cast<const sptr *>(VTable + OffsetHere);
|
||||
}
|
||||
if (isDerivedFromAtOffset(Object + OffsetHere,
|
||||
VTI->base_info[base].__base_type, Base,
|
||||
Offset - OffsetHere))
|
||||
abi::__base_class_type_info::__virtual_mask)
|
||||
// For now, just punt on virtual bases and say 'yes'.
|
||||
// FIXME: OffsetHere is the offset in the vtable of the virtual base
|
||||
// offset. Read the vbase offset out of the vtable and use it.
|
||||
return true;
|
||||
if (isDerivedFromAtOffset(VTI->base_info[base].__base_type,
|
||||
Base, Offset - OffsetHere))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -152,15 +151,14 @@ static bool isDerivedFromAtOffset(sptr Object,
|
||||
|
||||
/// \brief Find the derived-most dynamic base class of \p Derived at offset
|
||||
/// \p Offset.
|
||||
static const abi::__class_type_info *
|
||||
findBaseAtOffset(sptr Object, const abi::__class_type_info *Derived,
|
||||
sptr Offset) {
|
||||
static const abi::__class_type_info *findBaseAtOffset(
|
||||
const abi::__class_type_info *Derived, sptr Offset) {
|
||||
if (!Offset)
|
||||
return Derived;
|
||||
|
||||
if (const abi::__si_class_type_info *SI =
|
||||
dynamic_cast<const abi::__si_class_type_info*>(Derived))
|
||||
return findBaseAtOffset(Object, SI->__base_type, Offset);
|
||||
return findBaseAtOffset(SI->__base_type, Offset);
|
||||
|
||||
const abi::__vmi_class_type_info *VTI =
|
||||
dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
|
||||
@ -172,13 +170,12 @@ findBaseAtOffset(sptr Object, const abi::__class_type_info *Derived,
|
||||
sptr OffsetHere = VTI->base_info[base].__offset_flags >>
|
||||
abi::__base_class_type_info::__offset_shift;
|
||||
if (VTI->base_info[base].__offset_flags &
|
||||
abi::__base_class_type_info::__virtual_mask) {
|
||||
sptr VTable = *reinterpret_cast<const sptr *>(Object);
|
||||
OffsetHere = *reinterpret_cast<const sptr *>(VTable + OffsetHere);
|
||||
}
|
||||
if (const abi::__class_type_info *Base = findBaseAtOffset(
|
||||
Object + OffsetHere, VTI->base_info[base].__base_type,
|
||||
Offset - OffsetHere))
|
||||
abi::__base_class_type_info::__virtual_mask)
|
||||
// FIXME: Can't handle virtual bases yet.
|
||||
continue;
|
||||
if (const abi::__class_type_info *Base =
|
||||
findBaseAtOffset(VTI->base_info[base].__base_type,
|
||||
Offset - OffsetHere))
|
||||
return Base;
|
||||
}
|
||||
|
||||
@ -230,8 +227,7 @@ bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
|
||||
return false;
|
||||
|
||||
abi::__class_type_info *Base = (abi::__class_type_info*)Type;
|
||||
if (!isDerivedFromAtOffset(reinterpret_cast<sptr>(Object), Derived, Base,
|
||||
-Vtable->Offset))
|
||||
if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset))
|
||||
return false;
|
||||
|
||||
// Success. Cache this result.
|
||||
@ -245,9 +241,8 @@ __ubsan::DynamicTypeInfo __ubsan::getDynamicTypeInfo(void *Object) {
|
||||
if (!Vtable)
|
||||
return DynamicTypeInfo(0, 0, 0);
|
||||
const abi::__class_type_info *ObjectType = findBaseAtOffset(
|
||||
reinterpret_cast<sptr>(Object),
|
||||
static_cast<const abi::__class_type_info *>(Vtable->TypeInfo),
|
||||
-Vtable->Offset);
|
||||
static_cast<const abi::__class_type_info*>(Vtable->TypeInfo),
|
||||
-Vtable->Offset);
|
||||
return DynamicTypeInfo(Vtable->TypeInfo->__type_name, -Vtable->Offset,
|
||||
ObjectType ? ObjectType->__type_name : "<unknown>");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user