mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 06:40:01 +08:00
ubsan: Add checking for invalid downcasts. Per [expr.static.cast]p2 and p11,
base-to-derived casts have undefined behavior if the object is not actually an instance of the derived type. Runtime library part. llvm-svn: 175079
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
// RUN: %clang -ccc-cxx -fsanitize=vptr %s -O3 -o %t
|
||||
// RUN: %t rT && %t mT && %t fT
|
||||
// RUN: %t rU && %t mU && %t fU
|
||||
// RUN: %t rT && %t mT && %t fT && %t cT
|
||||
// RUN: %t rU && %t mU && %t fU && %t cU
|
||||
// RUN: %t rS && %t rV && %t oV
|
||||
// RUN: %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --strict-whitespace
|
||||
// RUN: %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
|
||||
// RUN: %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --strict-whitespace
|
||||
// RUN: %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --strict-whitespace
|
||||
// RUN: %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
|
||||
// RUN: %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --strict-whitespace
|
||||
// RUN: %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --strict-whitespace
|
||||
// RUN: %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --strict-whitespace
|
||||
|
||||
@@ -102,5 +104,14 @@ int main(int, char **argv) {
|
||||
// CHECK-OFFSET-NEXT: {{^ \^ ( ~~~~~~~~~~~~)~~~~~~~~~~~ *$}}
|
||||
// CHECK-OFFSET-NEXT: {{^ ( )?vptr for}} 'T' base class of [[DYN_TYPE]]
|
||||
return reinterpret_cast<U*>(p)->v() - 2;
|
||||
|
||||
case 'c':
|
||||
// CHECK-DOWNCAST: vptr.cpp:[[@LINE+5]]:5: runtime error: downcast of address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
|
||||
// CHECK-DOWNCAST-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']]
|
||||
// CHECK-DOWNCAST-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }}
|
||||
// CHECK-DOWNCAST-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
|
||||
// CHECK-DOWNCAST-NEXT: {{^ vptr for}} [[DYN_TYPE]]
|
||||
static_cast<T*>(reinterpret_cast<S*>(p));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace __ubsan;
|
||||
namespace __ubsan {
|
||||
const char *TypeCheckKinds[] = {
|
||||
"load of", "store to", "reference binding to", "member access within",
|
||||
"member call on", "constructor call on"
|
||||
"member call on", "constructor call on", "downcast of", "downcast of"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ static void HandleDynamicTypeCacheMiss(
|
||||
<< TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
|
||||
|
||||
// If possible, say what type it actually points to.
|
||||
// FIXME: Demangle the type names.
|
||||
DynamicTypeInfo DTI = getDynamicTypeInfo((void*)Pointer);
|
||||
if (!DTI.isValid())
|
||||
Diag(Pointer, DL_Note, "object has invalid vptr")
|
||||
|
||||
Reference in New Issue
Block a user